[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
|
// Check if we're trying to suspend ourselves
|
||||||
bool is_current_thread = pthread_self() == thread_;
|
bool is_current_thread = pthread_self() == thread_;
|
||||||
|
bool already_suspended = false;
|
||||||
|
|
||||||
{
|
{
|
||||||
std::unique_lock lock(state_mutex_);
|
std::unique_lock lock(state_mutex_);
|
||||||
if (out_previous_suspend_count) {
|
if (out_previous_suspend_count) {
|
||||||
*out_previous_suspend_count = suspend_count_;
|
*out_previous_suspend_count = suspend_count_;
|
||||||
}
|
}
|
||||||
|
already_suspended = (state_ == State::kSuspended);
|
||||||
state_ = State::kSuspended;
|
state_ = State::kSuspended;
|
||||||
++suspend_count_;
|
++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) {
|
if (is_current_thread) {
|
||||||
// Self-suspension: Instead of sending a signal, directly call
|
// Self-suspension: Instead of sending a signal, directly call
|
||||||
// WaitSuspended. This avoids the signal handler complexity for the
|
// WaitSuspended. This avoids the signal handler complexity for the
|
||||||
|
|||||||
Reference in New Issue
Block a user