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:
+38
-30
@@ -287,6 +287,7 @@ static DoublyLinkedList<block_cache> sCaches;
|
|||||||
static mutex sCachesLock;
|
static mutex sCachesLock;
|
||||||
static sem_id sEventSemaphore;
|
static sem_id sEventSemaphore;
|
||||||
static mutex sNotificationsLock;
|
static mutex sNotificationsLock;
|
||||||
|
static thread_id sWriterNotifyThread;
|
||||||
static DoublyLinkedListLink<block_cache> sMarkCache;
|
static DoublyLinkedListLink<block_cache> sMarkCache;
|
||||||
// TODO: this only works if the link is the first entry of block_cache
|
// TODO: this only works if the link is the first entry of block_cache
|
||||||
static object_cache *sBlockCache;
|
static object_cache *sBlockCache;
|
||||||
@@ -1353,33 +1354,6 @@ dump_caches(int argc, char **argv)
|
|||||||
#endif // DEBUG_BLOCK_CACHE
|
#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, ¬ification, TRANSACTION_WRITTEN, false);
|
|
||||||
|
|
||||||
// wait for notification hook to be called
|
|
||||||
entry.Wait();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static block_cache *
|
static block_cache *
|
||||||
get_next_locked_block_cache(block_cache *last)
|
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, ¬ification, TRANSACTION_WRITTEN, false);
|
||||||
|
|
||||||
|
// wait for notification hook to be called
|
||||||
|
entry.Wait();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
extern "C" status_t
|
extern "C" status_t
|
||||||
block_cache_init(void)
|
block_cache_init(void)
|
||||||
{
|
{
|
||||||
@@ -1577,10 +1585,10 @@ block_cache_init(void)
|
|||||||
if (sEventSemaphore < B_OK)
|
if (sEventSemaphore < B_OK)
|
||||||
return sEventSemaphore;
|
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);
|
"block writer/notifier", B_LOW_PRIORITY, NULL);
|
||||||
if (thread >= B_OK)
|
if (sWriterNotifyThread >= B_OK)
|
||||||
send_signal_etc(thread, SIGCONT, B_DO_NOT_RESCHEDULE);
|
send_signal_etc(sWriterNotifyThread, SIGCONT, B_DO_NOT_RESCHEDULE);
|
||||||
|
|
||||||
#ifdef DEBUG_BLOCK_CACHE
|
#ifdef DEBUG_BLOCK_CACHE
|
||||||
add_debugger_command_etc("block_caches", &dump_caches,
|
add_debugger_command_etc("block_caches", &dump_caches,
|
||||||
|
|||||||
Reference in New Issue
Block a user