From ddd20af422537594bbfa86b0b5b9b0c486249083 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Wed, 5 Nov 2008 11:16:04 +0000 Subject: [PATCH] * Fixed a potential race condition: when wait_for_notifications() is called from the block notifier, the cache could be deleted before we have the chance to lock it. We now lock the sCachesLock, and see if this cache is still valid. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28512 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/system/kernel/cache/block_cache.cpp | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/system/kernel/cache/block_cache.cpp b/src/system/kernel/cache/block_cache.cpp index 6902134302..c1dc688142 100644 --- a/src/system/kernel/cache/block_cache.cpp +++ b/src/system/kernel/cache/block_cache.cpp @@ -1746,6 +1746,22 @@ notify_sync(int32 transactionID, int32 event, void* _cache) } +/*! Must be called with the sCachesLock held. */ +static bool +is_valid_cache(block_cache* cache) +{ + ASSERT_LOCKED_MUTEX(&sCachesLock); + + DoublyLinkedList::Iterator iterator = sCaches.GetIterator(); + while (iterator.HasNext()) { + if (cache == iterator.Next()) + return true; + } + + return false; +} + + /*! Waits until all pending notifications are carried out. Safe to be called from the block writer/notifier thread. You must not hold the \a cache lock when calling this function. @@ -1756,7 +1772,9 @@ wait_for_notifications(block_cache* cache) if (find_thread(NULL) == sNotifierWriterThread) { // We're the notifier thread, don't wait, but flush all pending // notifications directly. - flush_pending_notifications(cache); + MutexLocker _(sCachesLock); + if (is_valid_cache(cache)) + flush_pending_notifications(cache); return; }