@@ -69,33 +69,29 @@ void emscripten_thread_sleep(double msecs) {
69
69
double now = emscripten_get_now ();
70
70
double target = now + msecs ;
71
71
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
-
76
72
// 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 ;
78
74
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.
80
76
const double maxMsecsSliceToSleep = emscripten_is_main_runtime_thread () ? 1 : 100 ;
81
77
82
78
emscripten_conditional_set_current_thread_status (
83
79
EM_THREAD_STATUS_RUNNING , EM_THREAD_STATUS_SLEEPING );
84
- now = emscripten_get_now ();
85
- while (now < target ) {
80
+
81
+ double msecsToSleep ;
82
+ do {
86
83
// Keep processing the main loop of the calling thread.
87
84
__pthread_testcancel (); // pthreads spec: sleep is a cancellation point, so must test if this
88
85
// thread is cancelled during the sleep.
89
86
emscripten_current_thread_process_queued_calls ();
90
87
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 );
99
95
100
96
emscripten_conditional_set_current_thread_status (
101
97
EM_THREAD_STATUS_SLEEPING , EM_THREAD_STATUS_RUNNING );
@@ -369,25 +365,24 @@ static CallQueue* GetOrAllocateQueue(void* target) {
369
365
return q ;
370
366
}
371
367
368
+ // TODO(kleisauke): All paths call this with timeoutMSecs == INFINITY, perhaps drop this param?
372
369
EMSCRIPTEN_RESULT emscripten_wait_for_call_v (em_queued_call * call , double timeoutMSecs ) {
373
- int r ;
374
-
375
370
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 ;
391
386
}
392
387
393
388
EMSCRIPTEN_RESULT emscripten_wait_for_call_i (
@@ -444,7 +439,7 @@ int _emscripten_do_dispatch_to_thread(pthread_t target_thread, em_queued_call* c
444
439
// If queue of the main browser thread is full, then we wait. (never drop messages for the main
445
440
// browser thread)
446
441
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 );
448
443
pthread_mutex_lock (& call_queue_lock );
449
444
head = q -> call_queue_head ;
450
445
tail = q -> call_queue_tail ;
@@ -624,7 +619,7 @@ void emscripten_current_thread_process_queued_calls() {
624
619
pthread_mutex_unlock (& call_queue_lock );
625
620
626
621
// 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 );
628
623
629
624
thread_is_processing_queued_calls = false;
630
625
}
0 commit comments