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
This commit is contained in:
Axel Dörfler 2008-04-05 10:23:11 +00:00
parent 355914a2cd
commit 98b7d71b7c
1 changed files with 38 additions and 30 deletions

View File

@ -287,6 +287,7 @@ static DoublyLinkedList<block_cache> sCaches;
static mutex sCachesLock;
static sem_id sEventSemaphore;
static mutex sNotificationsLock;
static thread_id sWriterNotifyThread;
static DoublyLinkedListLink<block_cache> 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<block_cache> entry;
entry.Add(cache);
add_notification(cache, &notification, 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<block_cache> entry;
entry.Add(cache);
add_notification(cache, &notification, 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,