summaryrefslogtreecommitdiff
path: root/Utilities/cmlibuv/src/win/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'Utilities/cmlibuv/src/win/core.c')
-rw-r--r--Utilities/cmlibuv/src/win/core.c90
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);
}