diff options
Diffstat (limited to 'Utilities/cmlibuv/src/win/core.c')
-rw-r--r-- | Utilities/cmlibuv/src/win/core.c | 90 |
1 files changed, 47 insertions, 43 deletions
diff --git a/Utilities/cmlibuv/src/win/core.c b/Utilities/cmlibuv/src/win/core.c index e53a0f8e28..67af93e657 100644 --- a/Utilities/cmlibuv/src/win/core.c +++ b/Utilities/cmlibuv/src/win/core.c @@ -84,10 +84,12 @@ static int uv__loops_capacity; #define UV__LOOPS_CHUNK_SIZE 8 static uv_mutex_t uv__loops_lock; + static void uv__loops_init(void) { uv_mutex_init(&uv__loops_lock); } + static int uv__loops_add(uv_loop_t* loop) { uv_loop_t** new_loops; int new_capacity, i; @@ -115,6 +117,7 @@ failed_loops_realloc: return ERROR_OUTOFMEMORY; } + static void uv__loops_remove(uv_loop_t* loop) { int loop_index; int smaller_capacity; @@ -173,7 +176,7 @@ void uv__wake_all_loops(void) { uv_mutex_unlock(&uv__loops_lock); } -static void uv_init(void) { +static void uv__init(void) { /* Tell Windows that we will handle critical errors. */ SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); @@ -199,19 +202,19 @@ static void uv_init(void) { /* Fetch winapi function pointers. This must be done first because other * initialization code might need these function pointers to be loaded. */ - uv_winapi_init(); + uv__winapi_init(); /* Initialize winsock */ - uv_winsock_init(); + uv__winsock_init(); /* Initialize FS */ - uv_fs_init(); + uv__fs_init(); /* Initialize signal stuff */ - uv_signals_init(); + uv__signals_init(); /* Initialize console */ - uv_console_init(); + uv__console_init(); /* Initialize utilities */ uv__util_init(); @@ -327,7 +330,7 @@ void uv_update_time(uv_loop_t* loop) { void uv__once_init(void) { - uv_once(&uv_init_guard_, uv_init); + uv_once(&uv_init_guard_, uv__init); } @@ -395,23 +398,28 @@ int uv_loop_fork(uv_loop_t* loop) { } -int uv_backend_timeout(const uv_loop_t* loop) { - if (loop->stop_flag != 0) - return 0; - - if (!uv__has_active_handles(loop) && !uv__has_active_reqs(loop)) - return 0; +static int uv__loop_alive(const uv_loop_t* loop) { + return uv__has_active_handles(loop) || + uv__has_active_reqs(loop) || + loop->pending_reqs_tail != NULL || + loop->endgame_handles != NULL; +} - if (loop->pending_reqs_tail) - return 0; - if (loop->endgame_handles) - return 0; +int uv_loop_alive(const uv_loop_t* loop) { + return uv__loop_alive(loop); +} - if (loop->idle_handles) - return 0; - return uv__next_timeout(loop); +int uv_backend_timeout(const uv_loop_t* loop) { + if (loop->stop_flag == 0 && + /* uv__loop_alive(loop) && */ + (uv__has_active_handles(loop) || uv__has_active_reqs(loop)) && + loop->pending_reqs_tail == NULL && + loop->idle_handles == NULL && + loop->endgame_handles == NULL) + return uv__next_timeout(loop); + return 0; } @@ -462,8 +470,8 @@ static void uv__poll_wine(uv_loop_t* loop, DWORD timeout) { if (overlapped) { /* Package was dequeued */ - req = uv_overlapped_to_req(overlapped); - uv_insert_pending_req(loop, req); + req = uv__overlapped_to_req(overlapped); + uv__insert_pending_req(loop, req); /* Some time might have passed waiting for I/O, * so update the loop time here. @@ -547,8 +555,8 @@ static void uv__poll(uv_loop_t* loop, DWORD timeout) { * meant only to wake us up. */ if (overlappeds[i].lpOverlapped) { - req = uv_overlapped_to_req(overlappeds[i].lpOverlapped); - uv_insert_pending_req(loop, req); + req = uv__overlapped_to_req(overlappeds[i].lpOverlapped); + uv__insert_pending_req(loop, req); } } @@ -581,22 +589,10 @@ static void uv__poll(uv_loop_t* loop, DWORD timeout) { } -static int uv__loop_alive(const uv_loop_t* loop) { - return uv__has_active_handles(loop) || - uv__has_active_reqs(loop) || - loop->endgame_handles != NULL; -} - - -int uv_loop_alive(const uv_loop_t* loop) { - return uv__loop_alive(loop); -} - - int uv_run(uv_loop_t *loop, uv_run_mode mode) { DWORD timeout; int r; - int ran_pending; + int can_sleep; r = uv__loop_alive(loop); if (!r) @@ -606,12 +602,14 @@ int uv_run(uv_loop_t *loop, uv_run_mode mode) { uv_update_time(loop); uv__run_timers(loop); - ran_pending = uv_process_reqs(loop); - uv_idle_invoke(loop); - uv_prepare_invoke(loop); + can_sleep = loop->pending_reqs_tail == NULL && loop->idle_handles == NULL; + + uv__process_reqs(loop); + uv__idle_invoke(loop); + uv__prepare_invoke(loop); timeout = 0; - if ((mode == UV_RUN_ONCE && !ran_pending) || mode == UV_RUN_DEFAULT) + if ((mode == UV_RUN_ONCE && can_sleep) || mode == UV_RUN_DEFAULT) timeout = uv_backend_timeout(loop); if (pGetQueuedCompletionStatusEx) @@ -619,6 +617,11 @@ int uv_run(uv_loop_t *loop, uv_run_mode mode) { else uv__poll_wine(loop, timeout); + /* Process immediate callbacks (e.g. write_cb) a small fixed number of + * times to avoid loop starvation.*/ + for (r = 0; r < 8 && loop->pending_reqs_tail != NULL; r++) + uv__process_reqs(loop); + /* Run one final update on the provider_idle_time in case uv__poll* * returned because the timeout expired, but no events were received. This * call will be ignored if the provider_entry_time was either never set (if @@ -626,8 +629,8 @@ int uv_run(uv_loop_t *loop, uv_run_mode mode) { */ uv__metrics_update_idle_time(loop); - uv_check_invoke(loop); - uv_process_endgames(loop); + uv__check_invoke(loop); + uv__process_endgames(loop); if (mode == UV_RUN_ONCE) { /* UV_RUN_ONCE implies forward progress: at least one callback must have @@ -638,6 +641,7 @@ int uv_run(uv_loop_t *loop, uv_run_mode mode) { * UV_RUN_NOWAIT makes no guarantees about progress so it's omitted from * the check. */ + uv_update_time(loop); uv__run_timers(loop); } |