diff --git a/system/lib/libc/musl/src/thread/pthread_mutex_timedlock.c b/system/lib/libc/musl/src/thread/pthread_mutex_timedlock.c index 0a240e7913418..fdaf9fca76fdf 100644 --- a/system/lib/libc/musl/src/thread/pthread_mutex_timedlock.c +++ b/system/lib/libc/musl/src/thread/pthread_mutex_timedlock.c @@ -20,7 +20,19 @@ int __pthread_mutex_timedlock(pthread_mutex_t *restrict m, const struct timespec if ((m->_m_type&3) == PTHREAD_MUTEX_ERRORCHECK && (r&0x7fffffff) == __pthread_self()->tid) return EDEADLK; - +#ifdef __EMSCRIPTEN__ + // If no time is given, do not sleep forever - there is a possible race + // condition here. We need to keep iterating in this loop, since _m_lock + // may be set to the value we want *just* before the __timedwait. __timedwait + // does not check if the value is what we want, it just checks for a wake on + // that address, so it would wait forever. + // Instead of picking some arbitrary time to wait, just keep busy-waiting. + if (!at) { + r = pthread_mutex_trylock(m); + if (r != EBUSY) return r; + } + continue; +#endif a_inc(&m->_m_waiters); t = r | 0x80000000; a_cas(&m->_m_lock, r, t);