From 98b7d71b7cd2205532e3da8d45c0a9d49ce7cfba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Sat, 5 Apr 2008 10:23:11 +0000 Subject: [PATCH] The wait_for_notifications() function now detects if it has been run from within the notifier/writer thread, and will then flush the notifications directly. This should fix #2008 again. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24806 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/system/kernel/cache/block_cache.cpp | 68 ++++++++++++++----------- 1 file changed, 38 insertions(+), 30 deletions(-) diff --git a/src/system/kernel/cache/block_cache.cpp b/src/system/kernel/cache/block_cache.cpp index b47217fe1e..6e479c8b71 100644 --- a/src/system/kernel/cache/block_cache.cpp +++ b/src/system/kernel/cache/block_cache.cpp @@ -287,6 +287,7 @@ static DoublyLinkedList sCaches; static mutex sCachesLock; static sem_id sEventSemaphore; static mutex sNotificationsLock; +static thread_id sWriterNotifyThread; static DoublyLinkedListLink sMarkCache; // TODO: this only works if the link is the first entry of block_cache static object_cache *sBlockCache; @@ -1353,33 +1354,6 @@ dump_caches(int argc, char **argv) #endif // DEBUG_BLOCK_CACHE -static void -notify_sync(int32 transactionID, int32 event, void *_cache) -{ - block_cache *cache = (block_cache *)_cache; - - cache->condition_variable.NotifyOne(); -} - - -static void -wait_for_notifications(block_cache *cache) -{ - // add sync notification - cache_notification notification; - set_notification(NULL, notification, TRANSACTION_WRITTEN, notify_sync, - cache); - - ConditionVariableEntry entry; - entry.Add(cache); - - add_notification(cache, ¬ification, TRANSACTION_WRITTEN, false); - - // wait for notification hook to be called - entry.Wait(); -} - - static block_cache * get_next_locked_block_cache(block_cache *last) { @@ -1559,6 +1533,40 @@ block_notifier_and_writer(void *) } +static void +notify_sync(int32 transactionID, int32 event, void *_cache) +{ + block_cache *cache = (block_cache *)_cache; + + cache->condition_variable.NotifyOne(); +} + + +static void +wait_for_notifications(block_cache *cache) +{ + if (find_thread(NULL) == sWriterNotifyThread) { + // We're the notifier thread, don't wait, but flush all pending + // notifications directly. + flush_pending_notifications(cache); + return; + } + + // add sync notification + cache_notification notification; + set_notification(NULL, notification, TRANSACTION_WRITTEN, notify_sync, + cache); + + ConditionVariableEntry entry; + entry.Add(cache); + + add_notification(cache, ¬ification, TRANSACTION_WRITTEN, false); + + // wait for notification hook to be called + entry.Wait(); +} + + extern "C" status_t block_cache_init(void) { @@ -1577,10 +1585,10 @@ block_cache_init(void) if (sEventSemaphore < B_OK) return sEventSemaphore; - thread_id thread = spawn_kernel_thread(&block_notifier_and_writer, + sWriterNotifyThread = spawn_kernel_thread(&block_notifier_and_writer, "block writer/notifier", B_LOW_PRIORITY, NULL); - if (thread >= B_OK) - send_signal_etc(thread, SIGCONT, B_DO_NOT_RESCHEDULE); + if (sWriterNotifyThread >= B_OK) + send_signal_etc(sWriterNotifyThread, SIGCONT, B_DO_NOT_RESCHEDULE); #ifdef DEBUG_BLOCK_CACHE add_debugger_command_etc("block_caches", &dump_caches,