[Threading/Posix] Fix issue with nested suspend
When SuspendThread is called on an already-suspended thread, it would send another pthread_kill signal, which would nest signal handlers and create multiple outstanding sem_wait calls while Resume only posts once when count reaches 0. Instead we increment suspend count and skip redundant signal.
This commit is contained in:
@@ -825,16 +825,26 @@ class PosixCondition<Thread> final : public PosixConditionBase {
|
||||
|
||||
// Check if we're trying to suspend ourselves
|
||||
bool is_current_thread = pthread_self() == thread_;
|
||||
bool already_suspended = false;
|
||||
|
||||
{
|
||||
std::unique_lock lock(state_mutex_);
|
||||
if (out_previous_suspend_count) {
|
||||
*out_previous_suspend_count = suspend_count_;
|
||||
}
|
||||
already_suspended = (state_ == State::kSuspended);
|
||||
state_ = State::kSuspended;
|
||||
++suspend_count_;
|
||||
}
|
||||
|
||||
// If already suspended, just increment the count — don't send another
|
||||
// signal. A second pthread_kill while the thread is in sem_wait would
|
||||
// nest signal handlers and create multiple outstanding sem_waits, but
|
||||
// Resume only posts once when count reaches 0.
|
||||
if (already_suspended) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (is_current_thread) {
|
||||
// Self-suspension: Instead of sending a signal, directly call
|
||||
// WaitSuspended. This avoids the signal handler complexity for the
|
||||
|
||||
Reference in New Issue
Block a user