Remove global condition waiter registry that deadlocks exception delivery

Co-authored-by: Bipin <bipinkrish4@gmail.com>
This commit is contained in:
nmzik 2026-09-14 21:27:05 +04:00
parent 437e69ef1b
commit 18a1e0fadc
5 changed files with 8 additions and 54 deletions

View File

@ -8,7 +8,6 @@
#include <chrono> // IWYU pragma: keep
#include <condition_variable> // IWYU pragma: keep
#include <mutex>
#include <vector>
#if KYTY_PLATFORM == KYTY_PLATFORM_WINDOWS && KYTY_COMPILER == KYTY_COMPILER_CLANG
#define KYTY_WIN_CS
@ -197,37 +196,7 @@ struct CondVarPrivate {
#endif
};
static std::recursive_mutex g_cond_waiters_mutex;
static std::vector<std::pair<int, CondVarPrivate*>> g_cond_waiters;
static wait_poll_func_t g_cond_wait_poll_callback = nullptr;
static void WakeCondVar(CondVarPrivate* cond_var) {
#ifdef KYTY_WIN_CS
static auto func = ResolveWakeAllConditionVariable();
EXIT_NOT_IMPLEMENTED(func == nullptr);
func(&cond_var->m_cv);
#else
cond_var->m_cv.notify_all();
#endif
}
static void RegisterCondWaiter(CondVarPrivate* cond_var) {
std::lock_guard lock(g_cond_waiters_mutex);
g_cond_waiters.emplace_back(Thread::GetThreadIdUnique(), cond_var);
}
static void UnregisterCondWaiter(CondVarPrivate* cond_var) {
const auto thread_id = Thread::GetThreadIdUnique();
std::lock_guard lock(g_cond_waiters_mutex);
const auto it = std::find_if(g_cond_waiters.begin(), g_cond_waiters.end(),
[thread_id, cond_var](const auto& waiter) {
return waiter.first == thread_id && waiter.second == cond_var;
});
if (it != g_cond_waiters.end()) {
g_cond_waiters.erase(it);
}
}
static wait_poll_func_t g_cond_wait_poll_callback = nullptr;
struct ThreadPrivate {
ThreadPrivate(thread_func_t f, void* a): func(f), arg(a), m_thread(&Run, this) {}
@ -365,7 +334,6 @@ CondVar::~CondVar() {
}
void CondVar::Wait(Mutex* mutex) {
RegisterCondWaiter(m_cond_var.get());
#ifndef KYTY_WIN_CS
std::unique_lock<std::recursive_mutex> cpp_lock(mutex->m_mutex->m_mutex, std::adopt_lock_t());
#endif
@ -406,7 +374,6 @@ void CondVar::Wait(Mutex* mutex) {
}
cpp_lock.release();
#endif
UnregisterCondWaiter(m_cond_var.get());
}
void CondVar::SetWaitPollCallback(wait_poll_func_t callback) {
@ -415,7 +382,6 @@ void CondVar::SetWaitPollCallback(wait_poll_func_t callback) {
bool CondVar::WaitFor(Mutex* mutex, uint32_t micros) {
bool ok = false;
RegisterCondWaiter(m_cond_var.get());
#ifndef KYTY_WIN_CS
std::unique_lock<std::recursive_mutex> cpp_lock(mutex->m_mutex->m_mutex, std::adopt_lock_t());
#endif
@ -430,7 +396,6 @@ bool CondVar::WaitFor(Mutex* mutex, uint32_t micros) {
std::cv_status::no_timeout);
cpp_lock.release();
#endif
UnregisterCondWaiter(m_cond_var.get());
return ok;
}
@ -445,16 +410,13 @@ void CondVar::Signal() {
}
void CondVar::SignalAll() {
WakeCondVar(m_cond_var.get());
}
void CondVar::SignalThread(int thread_id) {
std::lock_guard lock(g_cond_waiters_mutex);
for (const auto& waiter: g_cond_waiters) {
if (waiter.first == thread_id) {
WakeCondVar(waiter.second);
}
}
#ifdef KYTY_WIN_CS
static auto func = ResolveWakeAllConditionVariable();
EXIT_NOT_IMPLEMENTED(func == nullptr);
func(&m_cond_var->m_cv);
#else
m_cond_var->m_cv.notify_all();
#endif
}
int Thread::GetThreadIdUnique() {

View File

@ -77,7 +77,6 @@ public:
void Signal();
void SignalAll();
static void SignalThread(int thread_id);
static void SetWaitPollCallback(wait_poll_func_t callback);
KYTY_CLASS_NO_COPY(CondVar);

View File

@ -3093,10 +3093,6 @@ Pthread PthreadSwapSelfForSignal(Pthread thread) {
return previous;
}
int PthreadGetUniqueId(Pthread thread) {
return thread != nullptr ? thread->unique_id : 0;
}
uint64_t PthreadGetHostThreadId(Pthread thread) {
return thread != nullptr ? thread->host_thread_id : 0;
}

View File

@ -110,7 +110,6 @@ int KYTY_SYSV_ABI PthreadRename(Pthread thread, const char* name);
void KYTY_SYSV_ABI PthreadYield();
int KYTY_SYSV_ABI PthreadGetthreadid();
int KYTY_SYSV_ABI PthreadGetaffinity(Pthread thread, KernelCpumask* mask);
int PthreadGetUniqueId(Pthread thread);
uint64_t PthreadGetHostThreadId(Pthread thread);
void PthreadWakeForSignal(Pthread thread);
void PthreadQueuePendingSignal(Pthread thread, int signum);

View File

@ -1168,7 +1168,6 @@ static int KYTY_SYSV_ABI KernelRaiseException(Pthread thread, int signum) {
return KERNEL_ERROR_EINVAL;
}
Common::CondVar::SignalThread(PthreadGetUniqueId(thread));
PthreadWakeForSignal(thread);
CloseHandle(target_thread);
return OK;
@ -1193,7 +1192,6 @@ static int KYTY_SYSV_ABI KernelRaiseException(Pthread thread, int signum) {
return KERNEL_ERROR_EINVAL;
}
Common::CondVar::SignalThread(PthreadGetUniqueId(thread));
PthreadWakeForSignal(thread);
WaitForSignalDispatch(thread, signum);
return OK;