* Factored a delete_notification() that is now used in three places.
* remove_transaction_listeners() was checking the events_pending field without holding the sNotificatonLock - that should have been harmless (as we're in the middle of deleting the transaction), but it now looks better. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25130 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
dcc3839464
commit
2909d9dc26
46
src/system/kernel/cache/block_cache.cpp
vendored
46
src/system/kernel/cache/block_cache.cpp
vendored
@ -348,6 +348,21 @@ set_notification(cache_transaction *transaction,
|
||||
}
|
||||
|
||||
|
||||
/*! Makes sure the notification is deleted. It either deletes it directly,
|
||||
when possible, or marks it for deletion if the notification is pending.
|
||||
*/
|
||||
static void
|
||||
delete_notification(cache_notification *notification)
|
||||
{
|
||||
MutexLocker locker(sNotificationsLock);
|
||||
|
||||
if (notification->events_pending != 0)
|
||||
notification->delete_after_event = true;
|
||||
else
|
||||
delete notification;
|
||||
}
|
||||
|
||||
|
||||
/*! Adds the notification to the pending notifications list, or, if it's
|
||||
already part of it, updates its events_pending field.
|
||||
Also marks the notification to be deleted if \a deleteNotification
|
||||
@ -370,11 +385,7 @@ add_notification(block_cache *cache, cache_notification *notification,
|
||||
cache->pending_notifications.Add(notification);
|
||||
} else if (deleteNotification) {
|
||||
// we might need to delete it ourselves if we're late
|
||||
MutexLocker locker(sNotificationsLock);
|
||||
if (notification->events_pending != 0)
|
||||
notification->delete_after_event = true;
|
||||
else
|
||||
delete notification;
|
||||
delete_notification(notification);
|
||||
}
|
||||
|
||||
release_sem_etc(sEventSemaphore, 1, B_DO_NOT_RESCHEDULE);
|
||||
@ -408,14 +419,8 @@ notify_transaction_listeners(block_cache *cache, cache_transaction *transaction,
|
||||
|
||||
if ((listener->events & event) != 0)
|
||||
add_notification(cache, listener, event, remove);
|
||||
else if (remove) {
|
||||
// we might need to defer the deletion if its currently in use
|
||||
MutexLocker locker(sNotificationsLock);
|
||||
if (listener->events_pending != 0)
|
||||
listener->delete_after_event = true;
|
||||
else
|
||||
delete listener;
|
||||
}
|
||||
else if (remove)
|
||||
delete_notification(listener);
|
||||
}
|
||||
}
|
||||
|
||||
@ -473,6 +478,9 @@ flush_pending_notifications()
|
||||
}
|
||||
|
||||
|
||||
/*! Removes and deletes all listeners that are still monitoring this
|
||||
transaction.
|
||||
*/
|
||||
static void
|
||||
remove_transaction_listeners(block_cache *cache, cache_transaction *transaction)
|
||||
{
|
||||
@ -481,17 +489,7 @@ remove_transaction_listeners(block_cache *cache, cache_transaction *transaction)
|
||||
cache_listener *listener = iterator.Next();
|
||||
iterator.Remove();
|
||||
|
||||
if (listener->events_pending != 0) {
|
||||
// This listener is already in the notification list - just
|
||||
// mark it to be deleted.
|
||||
MutexLocker _(sNotificationsLock);
|
||||
if (listener->events_pending != 0) {
|
||||
listener->delete_after_event = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
delete listener;
|
||||
delete_notification(listener);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user