From 0958031b2413459a92b6c0e79f6ea8857a96cf40 Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Thu, 6 Mar 2025 09:48:01 -0500 Subject: [PATCH] kernel/fifo: Don't unlock before unblock. Otherwise there is a race that can occur if the waiting thread is interrupted (or hasn't slept yet) while the writing thread tries to unblock it. Instead, don't call SetNotified again if we unblocked with a status of B_OK. This can only happen when we were notified by another thread successfully. Should help with #19458. Change-Id: Iad46b26374a01539f8765231d259392c231c786a Reviewed-on: https://review.haiku-os.org/c/haiku/+/9085 Reviewed-by: waddlesplash --- src/system/kernel/fs/fifo.cpp | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/system/kernel/fs/fifo.cpp b/src/system/kernel/fs/fifo.cpp index 75d1dcb666..0260ea3bd3 100644 --- a/src/system/kernel/fs/fifo.cpp +++ b/src/system/kernel/fs/fifo.cpp @@ -107,17 +107,11 @@ public: void Notify(status_t status = B_OK) { - InterruptsLocker _; - SpinLocker spinLocker(fLock); + InterruptsSpinLocker spinLocker(fLock); TRACE("ReadRequest %p::Notify(), fNotified %d\n", this, fNotified); if (!fNotified) { fNotified = true; - - // Whoever calls Notify() must hold the requests lock, - // so we can be sure this Request won't be deleted. - spinLocker.Unlock(); - thread_unblock(fThread, status); } } @@ -697,9 +691,11 @@ Inode::WaitForReadRequest(ReadRequest& request) rw_lock_read_unlock(&fChangeLock); status_t status = thread_block(); - // Before going to lock again, we need to make sure no one tries to - // unblock us. Otherwise that would screw with mutex_lock(). - request.SetNotified(true); + if (status != B_OK) { + // Before going to lock again, we need to make sure no one tries to + // unblock us. Otherwise that would screw with mutex_lock(). + request.SetNotified(true); + } rw_lock_read_lock(&fChangeLock);