@@ -69,33 +69,29 @@ void emscripten_thread_sleep(double msecs) {
6969 double now = emscripten_get_now ();
7070 double target = now + msecs ;
7171
72- __pthread_testcancel (); // pthreads spec: sleep is a cancellation point, so must test if this
73- // thread is cancelled during the sleep.
74- emscripten_current_thread_process_queued_calls ();
75-
7672 // If we have less than this many msecs left to wait, busy spin that instead.
77- const double minimumTimeSliceToSleep = 0.1 ;
73+ const double minTimeSliceToSleep = 0.1 ;
7874
79- // runtime thread may need to run proxied calls, so sleep in very small slices to be responsive.
75+ // Runtime thread may need to run proxied calls, so sleep in very small slices to be responsive.
8076 const double maxMsecsSliceToSleep = emscripten_is_main_runtime_thread () ? 1 : 100 ;
8177
8278 emscripten_conditional_set_current_thread_status (
8379 EM_THREAD_STATUS_RUNNING , EM_THREAD_STATUS_SLEEPING );
84- now = emscripten_get_now ();
85- while (now < target ) {
80+
81+ double msecsToSleep ;
82+ do {
8683 // Keep processing the main loop of the calling thread.
8784 __pthread_testcancel (); // pthreads spec: sleep is a cancellation point, so must test if this
8885 // thread is cancelled during the sleep.
8986 emscripten_current_thread_process_queued_calls ();
9087
91- now = emscripten_get_now ();
92- double msecsToSleep = target - now ;
93- if (msecsToSleep > maxMsecsSliceToSleep )
94- msecsToSleep = maxMsecsSliceToSleep ;
95- if (msecsToSleep >= minimumTimeSliceToSleep )
96- emscripten_futex_wait (& dummyZeroAddress , 0 , msecsToSleep );
97- now = emscripten_get_now ();
98- };
88+ msecsToSleep = target - emscripten_get_now ();
89+ if (msecsToSleep < minTimeSliceToSleep )
90+ continue ;
91+
92+ emscripten_futex_wait (& dummyZeroAddress , 0 ,
93+ msecsToSleep > maxMsecsSliceToSleep ? maxMsecsSliceToSleep : msecsToSleep );
94+ } while (msecsToSleep > 0 );
9995
10096 emscripten_conditional_set_current_thread_status (
10197 EM_THREAD_STATUS_SLEEPING , EM_THREAD_STATUS_RUNNING );
@@ -369,25 +365,24 @@ static CallQueue* GetOrAllocateQueue(void* target) {
369365 return q ;
370366}
371367
368+ // TODO(kleisauke): All paths call this with timeoutMSecs == INFINITY, perhaps drop this param?
372369EMSCRIPTEN_RESULT emscripten_wait_for_call_v (em_queued_call * call , double timeoutMSecs ) {
373- int r ;
374-
375370 int done = atomic_load (& call -> operationDone );
376- if (! done ) {
377- double now = emscripten_get_now ();
378- double waitEndTime = now + timeoutMSecs ;
379- emscripten_set_current_thread_status ( EM_THREAD_STATUS_WAITPROXY );
380- while (! done && now < waitEndTime ) {
381- r = emscripten_futex_wait ( & call -> operationDone , 0 , waitEndTime - now );
382- done = atomic_load (& call -> operationDone );
383- now = emscripten_get_now ( );
384- }
385- emscripten_set_current_thread_status ( EM_THREAD_STATUS_RUNNING );
386- }
387- if ( done )
388- return EMSCRIPTEN_RESULT_SUCCESS ;
389- else
390- return EMSCRIPTEN_RESULT_TIMED_OUT ;
371+ if (done ) return EMSCRIPTEN_RESULT_SUCCESS ;
372+
373+ emscripten_set_current_thread_status ( EM_THREAD_STATUS_WAITPROXY ) ;
374+
375+ double timeoutUntilTime = emscripten_get_now () + timeoutMSecs ;
376+ do {
377+ emscripten_futex_wait (& call -> operationDone , 0 , timeoutMSecs );
378+ done = atomic_load ( & call -> operationDone );
379+
380+ timeoutMSecs = timeoutUntilTime - emscripten_get_now ( );
381+ } while (! done && timeoutMSecs > 0 );
382+
383+ emscripten_set_current_thread_status ( EM_THREAD_STATUS_RUNNING ) ;
384+
385+ return done ? EMSCRIPTEN_RESULT_SUCCESS : EMSCRIPTEN_RESULT_TIMED_OUT ;
391386}
392387
393388EMSCRIPTEN_RESULT emscripten_wait_for_call_i (
@@ -444,7 +439,7 @@ int _emscripten_do_dispatch_to_thread(pthread_t target_thread, em_queued_call* c
444439 // If queue of the main browser thread is full, then we wait. (never drop messages for the main
445440 // browser thread)
446441 if (target_thread == emscripten_main_browser_thread_id ()) {
447- emscripten_futex_wait ((void * )& q -> call_queue_head , head , INFINITY );
442+ emscripten_futex_wait ((void * )& q -> call_queue_head , head , INFINITY );
448443 pthread_mutex_lock (& call_queue_lock );
449444 head = q -> call_queue_head ;
450445 tail = q -> call_queue_tail ;
@@ -624,7 +619,7 @@ void emscripten_current_thread_process_queued_calls() {
624619 pthread_mutex_unlock (& call_queue_lock );
625620
626621 // If the queue was full and we had waiters pending to get to put data to queue, wake them up.
627- emscripten_futex_wake ((void * )& q -> call_queue_head , 0x7FFFFFFF );
622+ emscripten_futex_wake ((void * )& q -> call_queue_head , INT_MAX );
628623
629624 thread_is_processing_queued_calls = false;
630625}
0 commit comments