From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shelley Vohr <shelley.vohr@gmail.com>
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 1e1fc94bfcc3dca90620d09fab1fe60060e17056..253f23e14d09a8c8d5c51545f71b7f03f064dbd6 100644
--- a/deps/uv/include/uv.h
+++ b/deps/uv/include/uv.h
@@ -1789,6 +1789,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 63f268f795f10072fe1c430d1242e3774bf9eea9..2811f063eef7329f87fbe43b28729c6b25f0a75b 100644
--- a/deps/uv/src/unix/core.c
+++ b/deps/uv/src/unix/core.c
@@ -897,8 +897,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;
@@ -933,8 +936,11 @@ void uv__io_stop(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
       loop->nfds--;
     }
   }
-  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);
+  }
 }
 
 
@@ -951,6 +957,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);
 }
 
 
