From 2909d9dc269d3d7a8d55b814ed09743c98575747 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Thu, 24 Apr 2008 16:23:10 +0000 Subject: [PATCH] * 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 --- src/system/kernel/cache/block_cache.cpp | 46 ++++++++++++------------- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/src/system/kernel/cache/block_cache.cpp b/src/system/kernel/cache/block_cache.cpp index f21731b938..662091a010 100644 --- a/src/system/kernel/cache/block_cache.cpp +++ b/src/system/kernel/cache/block_cache.cpp @@ -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); } }