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);