From 6d3065508f951d5a0146a842d10a48d83f30def9 Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Fri, 4 Aug 2023 15:16:55 -0400 Subject: [PATCH] kernel/condition_variable: Adjust notified count and wait-status returning. * If we received a wait status, always return with it. * Only count those entries for which we set the wait-status as having been notified. In conjunction with the prior commit, this fixes some rare deadlocks that could occur with timeouts or signals. --- src/system/kernel/condition_variable.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/system/kernel/condition_variable.cpp b/src/system/kernel/condition_variable.cpp index 7f9785f877..1dc8c4c0aa 100644 --- a/src/system/kernel/condition_variable.cpp +++ b/src/system/kernel/condition_variable.cpp @@ -1,6 +1,6 @@ /* * Copyright 2007-2011, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2019, Haiku, Inc. All rights reserved. + * Copyright 2019-2023, Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. */ @@ -198,6 +198,11 @@ ConditionVariableEntry::Wait(uint32 flags, bigtime_t timeout) error = thread_block(); _RemoveFromVariable(); + + // We need to always return the actual wait status, if we received one. + if (fWaitStatus <= 0) + return fWaitStatus; + return error; } @@ -417,9 +422,10 @@ ConditionVariable::_NotifyLocked(bool all, status_t result) // and spin while waiting for us to do so. if (lastWaitStatus == STATUS_WAITING) thread_unblock_locked(thread, result); + + notified++; } - notified++; if (!all) break; }