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
This commit is contained in:
Shelley Vohr 2018-07-30 10:34:54 -07:00
Родитель c798ba1b7d
Коммит a5bd5d5407
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: F13993A75599653C
2 изменённых файлов: 12 добавлений и 2 удалений

2
deps/uv/include/uv.h поставляемый
Просмотреть файл

@ -1569,6 +1569,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];

12
deps/uv/src/unix/core.c поставляемый
Просмотреть файл

@ -865,8 +865,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;
@ -902,8 +905,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);
}
}
@ -919,6 +925,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);
}