From fb2113985dbcc33e62c28781b929aeb2e18d4789 Mon Sep 17 00:00:00 2001 From: Martin Fleisz Date: Tue, 28 Oct 2025 13:15:08 +0100 Subject: [PATCH] [winpr,synch] Fix starvation in pollset_poll caused by emscripten_sleep Recent changes in `pollset_poll` added yielding the process using `emscripten_sleep` so event handlers can have time to process data and set events. However calling `emscripten_sleep` on every iteration when checking the pollset caused process starvation which slowed down the whole session massively. This commit fixes this issue by checking for signaled events 10 times before actually causing a yield. This avoids possible deadlocks while not slowing down the whole session pipeline. --- winpr/libwinpr/synch/pollset.c | 13 +++++++++++-- winpr/libwinpr/synch/pollset.h | 3 +++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/winpr/libwinpr/synch/pollset.c b/winpr/libwinpr/synch/pollset.c index 7a61451f6..725f6905c 100644 --- a/winpr/libwinpr/synch/pollset.c +++ b/winpr/libwinpr/synch/pollset.c @@ -148,9 +148,18 @@ int pollset_poll(WINPR_POLL_SET* set, DWORD dwMilliseconds) if (ret >= 0) { #if defined(__EMSCRIPTEN__) - /* Yield in emscripten so event handlers can be processed */ + /* If we have tried 10 times unsuccessfully we will yield in emscripten so pending event + * handlers might be run */ if (ret == 0) - emscripten_sleep(0); + { + if (++set->yieldCounter > 10) + { + emscripten_sleep(0); + set->yieldCounter = 0; + } + } + else + set->yieldCounter = 0; #endif return ret; } diff --git a/winpr/libwinpr/synch/pollset.h b/winpr/libwinpr/synch/pollset.h index 6e478e6c7..dc0df449c 100644 --- a/winpr/libwinpr/synch/pollset.h +++ b/winpr/libwinpr/synch/pollset.h @@ -55,6 +55,9 @@ struct winpr_poll_set #endif size_t fillIndex; size_t size; +#if defined(__EMSCRIPTEN__) + size_t yieldCounter; +#endif }; typedef struct winpr_poll_set WINPR_POLL_SET;