From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Shelley Vohr Date: Mon, 30 Jul 2018 10:34:54 -0700 Subject: feat: add uv_loop watcher_queue code Electron's Node Integration works by listening to Node's backend file descriptor in a separate thread; when an event is ready the backend file descriptor will trigger a new event for it, and the main thread will then iterate the libuv loop. For certain operations (ex. adding a timeout task) the backend file descriptor isn't informed, & as a result the main thread doesn't know it needs to iterate the libuv loop so the timeout task will never execute until something else trigger a new event. This commit should be removed when https://github.com/libuv/libuv/pull/1921 is merged diff --git a/deps/uv/include/uv.h b/deps/uv/include/uv.h index f97801cec2f41b104fae591277ffbb94c3b2f299..da648b3efd5948843c485d65035ae29c79eebc69 100644 --- a/deps/uv/include/uv.h +++ b/deps/uv/include/uv.h @@ -1657,6 +1657,8 @@ union uv_any_req { struct uv_loop_s { /* User data - use this for whatever. */ void* data; + /* Callback when loop's watcher queue updates. */ + void (*on_watcher_queue_updated)(uv_loop_t*); /* Loop reference counting. */ unsigned int active_handles; void* handle_queue[2]; diff --git a/deps/uv/src/unix/core.c b/deps/uv/src/unix/core.c index 202c75bbb5e94cb2e8a588b09d4fbfdfe1ccfe3a..041b1838c629ec828f2160ac735953f1bf986c01 100644 --- a/deps/uv/src/unix/core.c +++ b/deps/uv/src/unix/core.c @@ -892,8 +892,11 @@ void uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events) { return; #endif - if (QUEUE_EMPTY(&w->watcher_queue)) + if (QUEUE_EMPTY(&w->watcher_queue)) { QUEUE_INSERT_TAIL(&loop->watcher_queue, &w->watcher_queue); + if (loop->on_watcher_queue_updated) + loop->on_watcher_queue_updated(loop); + } if (loop->watchers[w->fd] == NULL) { loop->watchers[w->fd] = w; @@ -929,8 +932,11 @@ void uv__io_stop(uv_loop_t* loop, uv__io_t* w, unsigned int events) { w->events = 0; } } - else if (QUEUE_EMPTY(&w->watcher_queue)) + else if (QUEUE_EMPTY(&w->watcher_queue)) { QUEUE_INSERT_TAIL(&loop->watcher_queue, &w->watcher_queue); + if (loop->on_watcher_queue_updated) + loop->on_watcher_queue_updated(loop); + } } @@ -947,6 +953,8 @@ void uv__io_close(uv_loop_t* loop, uv__io_t* w) { void uv__io_feed(uv_loop_t* loop, uv__io_t* w) { if (QUEUE_EMPTY(&w->pending_queue)) QUEUE_INSERT_TAIL(&loop->pending_queue, &w->pending_queue); + if (loop->on_watcher_queue_updated) + loop->on_watcher_queue_updated(loop); }