Change the NodeMonitorService lock from a mutex to a recursive_lock. This
allows event listeners to add new listeners inside a node monitoring event (i.e. if one wants to add a listener for the entry that has just been created and triggered the current notification). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24760 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -176,7 +176,7 @@ class NodeMonitorService : public NotificationService {
|
|||||||
|
|
||||||
typedef OpenHashTable<HashDefinition> MonitorHash;
|
typedef OpenHashTable<HashDefinition> MonitorHash;
|
||||||
MonitorHash fMonitors;
|
MonitorHash fMonitors;
|
||||||
mutex fMutex;
|
recursive_lock fRecursiveLock;
|
||||||
};
|
};
|
||||||
|
|
||||||
static NodeMonitorService sNodeMonitorService;
|
static NodeMonitorService sNodeMonitorService;
|
||||||
@@ -226,19 +226,20 @@ notify_query_entry_created_or_removed(int32 opcode, port_id port, int32 token,
|
|||||||
|
|
||||||
NodeMonitorService::NodeMonitorService()
|
NodeMonitorService::NodeMonitorService()
|
||||||
{
|
{
|
||||||
mutex_init(&fMutex, "node monitor");
|
recursive_lock_init(&fRecursiveLock, "node monitor");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NodeMonitorService::~NodeMonitorService()
|
NodeMonitorService::~NodeMonitorService()
|
||||||
{
|
{
|
||||||
|
recursive_lock_destroy(&fRecursiveLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
NodeMonitorService::InitCheck()
|
NodeMonitorService::InitCheck()
|
||||||
{
|
{
|
||||||
return fMutex.sem >= B_OK ? B_OK : fMutex.sem;
|
return fRecursiveLock.sem >= B_OK ? B_OK : fRecursiveLock.sem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -384,7 +385,7 @@ NodeMonitorService::AddListener(io_context *context, dev_t device, ino_t node,
|
|||||||
TRACE(("%s(dev = %ld, node = %Ld, flags = %ld, listener = %p\n",
|
TRACE(("%s(dev = %ld, node = %Ld, flags = %ld, listener = %p\n",
|
||||||
__PRETTY_FUNCTION__, device, node, flags, ¬ificationListener));
|
__PRETTY_FUNCTION__, device, node, flags, ¬ificationListener));
|
||||||
|
|
||||||
MutexLocker _(fMutex);
|
RecursiveLocker _(fRecursiveLock);
|
||||||
|
|
||||||
node_monitor *monitor;
|
node_monitor *monitor;
|
||||||
status_t status = _GetMonitor(context, device, node, true, &monitor);
|
status_t status = _GetMonitor(context, device, node, true, &monitor);
|
||||||
@@ -405,7 +406,7 @@ NodeMonitorService::_UpdateListener(io_context *context, dev_t device,
|
|||||||
TRACE(("%s(dev = %ld, node = %Ld, flags = %ld, listener = %p\n",
|
TRACE(("%s(dev = %ld, node = %Ld, flags = %ld, listener = %p\n",
|
||||||
__PRETTY_FUNCTION__, device, node, flags, ¬ificationListener));
|
__PRETTY_FUNCTION__, device, node, flags, ¬ificationListener));
|
||||||
|
|
||||||
MutexLocker _(fMutex);
|
RecursiveLocker _(fRecursiveLock);
|
||||||
|
|
||||||
node_monitor *monitor;
|
node_monitor *monitor;
|
||||||
status_t status = _GetMonitor(context, device, node, false, &monitor);
|
status_t status = _GetMonitor(context, device, node, false, &monitor);
|
||||||
@@ -530,7 +531,7 @@ NodeMonitorService::NotifyEntryCreatedOrRemoved(int32 opcode, dev_t device,
|
|||||||
if (!name)
|
if (!name)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
MutexLocker locker(fMutex);
|
RecursiveLocker locker(fRecursiveLock);
|
||||||
|
|
||||||
// get the lists of all interested listeners
|
// get the lists of all interested listeners
|
||||||
interested_monitor_listener_list interestedListeners[3];
|
interested_monitor_listener_list interestedListeners[3];
|
||||||
@@ -575,7 +576,7 @@ NodeMonitorService::NotifyEntryMoved(dev_t device, ino_t fromDirectory,
|
|||||||
dev_t nodeDevice = device;
|
dev_t nodeDevice = device;
|
||||||
resolve_mount_point_to_volume_root(device, node, &nodeDevice, &node);
|
resolve_mount_point_to_volume_root(device, node, &nodeDevice, &node);
|
||||||
|
|
||||||
MutexLocker locker(fMutex);
|
RecursiveLocker locker(fRecursiveLock);
|
||||||
|
|
||||||
// get the lists of all interested listeners
|
// get the lists of all interested listeners
|
||||||
interested_monitor_listener_list interestedListeners[3];
|
interested_monitor_listener_list interestedListeners[3];
|
||||||
@@ -617,7 +618,7 @@ inline status_t
|
|||||||
NodeMonitorService::NotifyStatChanged(dev_t device, ino_t node,
|
NodeMonitorService::NotifyStatChanged(dev_t device, ino_t node,
|
||||||
uint32 statFields)
|
uint32 statFields)
|
||||||
{
|
{
|
||||||
MutexLocker locker(fMutex);
|
RecursiveLocker locker(fRecursiveLock);
|
||||||
|
|
||||||
// get the lists of all interested listeners
|
// get the lists of all interested listeners
|
||||||
interested_monitor_listener_list interestedListeners[3];
|
interested_monitor_listener_list interestedListeners[3];
|
||||||
@@ -662,7 +663,7 @@ NodeMonitorService::NotifyAttributeChanged(dev_t device, ino_t node,
|
|||||||
if (!attribute)
|
if (!attribute)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
MutexLocker locker(fMutex);
|
RecursiveLocker locker(fRecursiveLock);
|
||||||
|
|
||||||
// get the lists of all interested listeners
|
// get the lists of all interested listeners
|
||||||
interested_monitor_listener_list interestedListeners[3];
|
interested_monitor_listener_list interestedListeners[3];
|
||||||
@@ -694,7 +695,7 @@ NodeMonitorService::NotifyUnmount(dev_t device)
|
|||||||
{
|
{
|
||||||
TRACE(("unmounted device: %ld\n", device));
|
TRACE(("unmounted device: %ld\n", device));
|
||||||
|
|
||||||
MutexLocker locker(fMutex);
|
RecursiveLocker locker(fRecursiveLock);
|
||||||
|
|
||||||
// get the lists of all interested listeners
|
// get the lists of all interested listeners
|
||||||
interested_monitor_listener_list interestedListeners[3];
|
interested_monitor_listener_list interestedListeners[3];
|
||||||
@@ -724,7 +725,7 @@ NodeMonitorService::NotifyMount(dev_t device, dev_t parentDevice,
|
|||||||
TRACE(("mounted device: %ld, parent %ld:%Ld\n", device, parentDevice,
|
TRACE(("mounted device: %ld, parent %ld:%Ld\n", device, parentDevice,
|
||||||
parentDirectory));
|
parentDirectory));
|
||||||
|
|
||||||
MutexLocker locker(fMutex);
|
RecursiveLocker locker(fRecursiveLock);
|
||||||
|
|
||||||
// get the lists of all interested listeners
|
// get the lists of all interested listeners
|
||||||
interested_monitor_listener_list interestedListeners[3];
|
interested_monitor_listener_list interestedListeners[3];
|
||||||
@@ -752,7 +753,7 @@ NodeMonitorService::NotifyMount(dev_t device, dev_t parentDevice,
|
|||||||
inline status_t
|
inline status_t
|
||||||
NodeMonitorService::RemoveListeners(io_context *context)
|
NodeMonitorService::RemoveListeners(io_context *context)
|
||||||
{
|
{
|
||||||
MutexLocker locker(fMutex);
|
RecursiveLocker locker(fRecursiveLock);
|
||||||
|
|
||||||
while (!list_is_empty(&context->node_monitors)) {
|
while (!list_is_empty(&context->node_monitors)) {
|
||||||
// the _RemoveListener() method will also free the node_monitor
|
// the _RemoveListener() method will also free the node_monitor
|
||||||
@@ -826,7 +827,7 @@ NodeMonitorService::RemoveListener(io_context *context, dev_t device,
|
|||||||
TRACE(("%s(dev = %ld, node = %Ld, listener = %p\n",
|
TRACE(("%s(dev = %ld, node = %Ld, listener = %p\n",
|
||||||
__PRETTY_FUNCTION__, device, node, ¬ificationListener));
|
__PRETTY_FUNCTION__, device, node, ¬ificationListener));
|
||||||
|
|
||||||
MutexLocker _(fMutex);
|
RecursiveLocker _(fRecursiveLock);
|
||||||
|
|
||||||
// get the monitor for this device/node pair
|
// get the monitor for this device/node pair
|
||||||
node_monitor *monitor = _MonitorFor(device, node);
|
node_monitor *monitor = _MonitorFor(device, node);
|
||||||
@@ -854,7 +855,7 @@ NodeMonitorService::RemoveUserListeners(struct io_context *context,
|
|||||||
monitor_listener *listener = NULL;
|
monitor_listener *listener = NULL;
|
||||||
int32 count = 0;
|
int32 count = 0;
|
||||||
|
|
||||||
MutexLocker _(fMutex);
|
RecursiveLocker _(fRecursiveLock);
|
||||||
|
|
||||||
while ((listener = (monitor_listener*)list_get_next_item(
|
while ((listener = (monitor_listener*)list_get_next_item(
|
||||||
&context->node_monitors, listener)) != NULL) {
|
&context->node_monitors, listener)) != NULL) {
|
||||||
@@ -883,7 +884,7 @@ NodeMonitorService::UpdateUserListener(io_context *context, dev_t device,
|
|||||||
TRACE(("%s(dev = %ld, node = %Ld, flags = %ld, listener = %p\n",
|
TRACE(("%s(dev = %ld, node = %Ld, flags = %ld, listener = %p\n",
|
||||||
__PRETTY_FUNCTION__, device, node, flags, &userListener));
|
__PRETTY_FUNCTION__, device, node, flags, &userListener));
|
||||||
|
|
||||||
MutexLocker _(fMutex);
|
RecursiveLocker _(fRecursiveLock);
|
||||||
|
|
||||||
node_monitor *monitor;
|
node_monitor *monitor;
|
||||||
status_t status = _GetMonitor(context, device, node, true, &monitor);
|
status_t status = _GetMonitor(context, device, node, true, &monitor);
|
||||||
|
|||||||
Reference in New Issue
Block a user