зеркало из https://github.com/electron/electron.git
chore: update libuv patch for event loop integration (#31647)
* chore: update libuv patch for loop integration * chore: update patches Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
This commit is contained in:
Родитель
6b66fea67d
Коммит
4e66b072da
|
@ -1,5 +1,4 @@
|
|||
refactor_alter_child_process_fork_to_use_execute_script_with.patch
|
||||
feat_add_uv_loop_watcher_queue_code.patch
|
||||
feat_initialize_asar_support.patch
|
||||
expose_get_builtin_module_function.patch
|
||||
build_add_gn_build_files.patch
|
||||
|
@ -42,3 +41,4 @@ unix_remove_uv_cloexec_ioctl_3515.patch
|
|||
process_simplify_uv_write_int_calls_3519.patch
|
||||
macos_don_t_use_thread-unsafe_strtok_3524.patch
|
||||
process_fix_hang_after_note_exit_3521.patch
|
||||
feat_add_uv_loop_interrupt_on_io_change_option_to_uv_loop_configure.patch
|
||||
|
|
|
@ -0,0 +1,503 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Cheng Zhao <zcbenz@gmail.com>
|
||||
Date: Mon, 31 Jan 2022 20:56:58 +0900
|
||||
Subject: feat: add UV_LOOP_INTERRUPT_ON_IO_CHANGE option to uv_loop_configure
|
||||
|
||||
https://github.com/libuv/libuv/pull/3308
|
||||
|
||||
diff --git a/deps/uv/docs/src/loop.rst b/deps/uv/docs/src/loop.rst
|
||||
index 0f5ddfb3ca21b7e5b38d0a4ce4b9e77387597199..ba815202fb157aa82859ec0518523cf6f2ec6ba1 100644
|
||||
--- a/deps/uv/docs/src/loop.rst
|
||||
+++ b/deps/uv/docs/src/loop.rst
|
||||
@@ -73,7 +73,15 @@ API
|
||||
|
||||
This option is necessary to use :c:func:`uv_metrics_idle_time`.
|
||||
|
||||
+ - UV_LOOP_INTERRUPT_ON_IO_CHANGE: Interrupt the loop whenever a new IO
|
||||
+ event has been added or changed.
|
||||
+
|
||||
+ This option is usually when implementing event loop integration, to make
|
||||
+ the polling of backend fd interrupt to recognize the changes of IO events.
|
||||
+
|
||||
.. versionchanged:: 1.39.0 added the UV_METRICS_IDLE_TIME option.
|
||||
+ .. versionchanged:: 1.43.0 added the UV_LOOP_INTERRUPT_ON_IO_CHANGE option.
|
||||
+
|
||||
|
||||
.. c:function:: int uv_loop_close(uv_loop_t* loop)
|
||||
|
||||
diff --git a/deps/uv/include/uv.h b/deps/uv/include/uv.h
|
||||
index 606083c87de5790d7e66fc34aeaae9a58acb8ef4..824b0b77cf5f0a46dcb3855c44ac73faaba2055f 100644
|
||||
--- a/deps/uv/include/uv.h
|
||||
+++ b/deps/uv/include/uv.h
|
||||
@@ -252,7 +252,8 @@ typedef struct uv_statfs_s uv_statfs_t;
|
||||
|
||||
typedef enum {
|
||||
UV_LOOP_BLOCK_SIGNAL = 0,
|
||||
- UV_METRICS_IDLE_TIME
|
||||
+ UV_METRICS_IDLE_TIME,
|
||||
+ UV_LOOP_INTERRUPT_ON_IO_CHANGE
|
||||
} uv_loop_option;
|
||||
|
||||
typedef enum {
|
||||
diff --git a/deps/uv/src/unix/async.c b/deps/uv/src/unix/async.c
|
||||
index e1805c323795e5b0c465d80100eebeb7bf838caa..dd4358c0cdaa97ba8fadf4d9755993803beddd18 100644
|
||||
--- a/deps/uv/src/unix/async.c
|
||||
+++ b/deps/uv/src/unix/async.c
|
||||
@@ -38,7 +38,6 @@
|
||||
#include <sys/eventfd.h>
|
||||
#endif
|
||||
|
||||
-static void uv__async_send(uv_loop_t* loop);
|
||||
static int uv__async_start(uv_loop_t* loop);
|
||||
|
||||
|
||||
@@ -70,7 +69,7 @@ int uv_async_send(uv_async_t* handle) {
|
||||
return 0;
|
||||
|
||||
/* Wake up the other thread's event loop. */
|
||||
- uv__async_send(handle->loop);
|
||||
+ uv__loop_interrupt(handle->loop);
|
||||
|
||||
/* Tell the other thread we're done. */
|
||||
if (cmpxchgi(&handle->pending, 1, 2) != 1)
|
||||
@@ -165,40 +164,6 @@ static void uv__async_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
|
||||
}
|
||||
|
||||
|
||||
-static void uv__async_send(uv_loop_t* loop) {
|
||||
- const void* buf;
|
||||
- ssize_t len;
|
||||
- int fd;
|
||||
- int r;
|
||||
-
|
||||
- buf = "";
|
||||
- len = 1;
|
||||
- fd = loop->async_wfd;
|
||||
-
|
||||
-#if defined(__linux__)
|
||||
- if (fd == -1) {
|
||||
- static const uint64_t val = 1;
|
||||
- buf = &val;
|
||||
- len = sizeof(val);
|
||||
- fd = loop->async_io_watcher.fd; /* eventfd */
|
||||
- }
|
||||
-#endif
|
||||
-
|
||||
- do
|
||||
- r = write(fd, buf, len);
|
||||
- while (r == -1 && errno == EINTR);
|
||||
-
|
||||
- if (r == len)
|
||||
- return;
|
||||
-
|
||||
- if (r == -1)
|
||||
- if (errno == EAGAIN || errno == EWOULDBLOCK)
|
||||
- return;
|
||||
-
|
||||
- abort();
|
||||
-}
|
||||
-
|
||||
-
|
||||
static int uv__async_start(uv_loop_t* loop) {
|
||||
int pipefd[2];
|
||||
int err;
|
||||
diff --git a/deps/uv/src/unix/core.c b/deps/uv/src/unix/core.c
|
||||
index 7cd3a2a954ff7d70e6ba7a6f7538648841bc54b2..f89b7158218be60ac10e61484a2d5e5e28a3182f 100644
|
||||
--- a/deps/uv/src/unix/core.c
|
||||
+++ b/deps/uv/src/unix/core.c
|
||||
@@ -887,6 +887,9 @@ void uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
|
||||
loop->watchers[w->fd] = w;
|
||||
loop->nfds++;
|
||||
}
|
||||
+
|
||||
+ if (uv__get_internal_fields(loop)->flags & UV_LOOP_INTERRUPT_ON_IO_CHANGE)
|
||||
+ uv__loop_interrupt(loop);
|
||||
}
|
||||
|
||||
|
||||
@@ -918,6 +921,9 @@ void uv__io_stop(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
|
||||
}
|
||||
else if (QUEUE_EMPTY(&w->watcher_queue))
|
||||
QUEUE_INSERT_TAIL(&loop->watcher_queue, &w->watcher_queue);
|
||||
+
|
||||
+ if (uv__get_internal_fields(loop)->flags & UV_LOOP_INTERRUPT_ON_IO_CHANGE)
|
||||
+ uv__loop_interrupt(loop);
|
||||
}
|
||||
|
||||
|
||||
@@ -934,6 +940,9 @@ 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 (uv__get_internal_fields(loop)->flags & UV_LOOP_INTERRUPT_ON_IO_CHANGE)
|
||||
+ uv__loop_interrupt(loop);
|
||||
}
|
||||
|
||||
|
||||
diff --git a/deps/uv/src/unix/loop.c b/deps/uv/src/unix/loop.c
|
||||
index a88e71c339351f2ebcdd6c3f933fc3b1122910ed..353143e5ebecae598425dc036f4458bb7c43bb0b 100644
|
||||
--- a/deps/uv/src/unix/loop.c
|
||||
+++ b/deps/uv/src/unix/loop.c
|
||||
@@ -217,6 +217,11 @@ int uv__loop_configure(uv_loop_t* loop, uv_loop_option option, va_list ap) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
+ if (option == UV_LOOP_INTERRUPT_ON_IO_CHANGE) {
|
||||
+ lfields->flags |= UV_LOOP_INTERRUPT_ON_IO_CHANGE;
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
if (option != UV_LOOP_BLOCK_SIGNAL)
|
||||
return UV_ENOSYS;
|
||||
|
||||
@@ -226,3 +231,37 @@ int uv__loop_configure(uv_loop_t* loop, uv_loop_option option, va_list ap) {
|
||||
loop->flags |= UV_LOOP_BLOCK_SIGPROF;
|
||||
return 0;
|
||||
}
|
||||
+
|
||||
+
|
||||
+void uv__loop_interrupt(uv_loop_t* loop) {
|
||||
+ const void* buf;
|
||||
+ ssize_t len;
|
||||
+ int fd;
|
||||
+ int r;
|
||||
+
|
||||
+ buf = "";
|
||||
+ len = 1;
|
||||
+ fd = loop->async_wfd;
|
||||
+
|
||||
+#if defined(__linux__)
|
||||
+ if (fd == -1) {
|
||||
+ static const uint64_t val = 1;
|
||||
+ buf = &val;
|
||||
+ len = sizeof(val);
|
||||
+ fd = loop->async_io_watcher.fd; /* eventfd */
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
+ do
|
||||
+ r = write(fd, buf, len);
|
||||
+ while (r == -1 && errno == EINTR);
|
||||
+
|
||||
+ if (r == len)
|
||||
+ return;
|
||||
+
|
||||
+ if (r == -1)
|
||||
+ if (errno == EAGAIN || errno == EWOULDBLOCK)
|
||||
+ return;
|
||||
+
|
||||
+ abort();
|
||||
+}
|
||||
diff --git a/deps/uv/src/uv-common.h b/deps/uv/src/uv-common.h
|
||||
index 6001b0cf68d0b0268b578218b664a737f43c9521..5d2212571f4bcb648ab332f0c5650d0fdb37c03a 100644
|
||||
--- a/deps/uv/src/uv-common.h
|
||||
+++ b/deps/uv/src/uv-common.h
|
||||
@@ -140,6 +140,8 @@ int uv__loop_configure(uv_loop_t* loop, uv_loop_option option, va_list ap);
|
||||
|
||||
void uv__loop_close(uv_loop_t* loop);
|
||||
|
||||
+void uv__loop_interrupt(uv_loop_t* loop);
|
||||
+
|
||||
int uv__read_start(uv_stream_t* stream,
|
||||
uv_alloc_cb alloc_cb,
|
||||
uv_read_cb read_cb);
|
||||
@@ -268,6 +270,10 @@ void uv__threadpool_cleanup(void);
|
||||
if (((h)->flags & UV_HANDLE_ACTIVE) != 0) break; \
|
||||
(h)->flags |= UV_HANDLE_ACTIVE; \
|
||||
if (((h)->flags & UV_HANDLE_REF) != 0) uv__active_handle_add(h); \
|
||||
+ int loop_flags = uv__get_internal_fields((h)->loop)->flags; \
|
||||
+ if (loop_flags & UV_LOOP_INTERRUPT_ON_IO_CHANGE) { \
|
||||
+ uv__loop_interrupt((h)->loop); \
|
||||
+ } \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
diff --git a/deps/uv/src/win/core.c b/deps/uv/src/win/core.c
|
||||
index e53a0f8e28637a58ceec7852d1a79874fc1a9548..dd4065c1cc68763bfe258492e3119669311394dc 100644
|
||||
--- a/deps/uv/src/win/core.c
|
||||
+++ b/deps/uv/src/win/core.c
|
||||
@@ -381,10 +381,20 @@ int uv__loop_configure(uv_loop_t* loop, uv_loop_option option, va_list ap) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
+ if (option == UV_LOOP_INTERRUPT_ON_IO_CHANGE) {
|
||||
+ lfields->flags |= UV_LOOP_INTERRUPT_ON_IO_CHANGE;
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
return UV_ENOSYS;
|
||||
}
|
||||
|
||||
|
||||
+void uv__loop_interrupt(uv_loop_t* loop) {
|
||||
+ PostQueuedCompletionStatus(loop->iocp, 0, 0, NULL);
|
||||
+}
|
||||
+
|
||||
+
|
||||
int uv_backend_fd(const uv_loop_t* loop) {
|
||||
return -1;
|
||||
}
|
||||
diff --git a/deps/uv/test/test-embed.c b/deps/uv/test/test-embed.c
|
||||
index c6ddceb149d9c1d68b0dd17b6dac0d4c3c3e9dbc..f6572c5dc2b6ef39bd11889ad1f7873007a6437d 100644
|
||||
--- a/deps/uv/test/test-embed.c
|
||||
+++ b/deps/uv/test/test-embed.c
|
||||
@@ -25,115 +25,179 @@
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
-#ifndef HAVE_KQUEUE
|
||||
-# if defined(__APPLE__) || \
|
||||
- defined(__DragonFly__) || \
|
||||
- defined(__FreeBSD__) || \
|
||||
- defined(__FreeBSD_kernel__) || \
|
||||
- defined(__OpenBSD__) || \
|
||||
- defined(__NetBSD__)
|
||||
-# define HAVE_KQUEUE 1
|
||||
-# endif
|
||||
-#endif
|
||||
-
|
||||
#ifndef HAVE_EPOLL
|
||||
# if defined(__linux__)
|
||||
# define HAVE_EPOLL 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
-#if defined(HAVE_KQUEUE) || defined(HAVE_EPOLL)
|
||||
+#if defined(HAVE_EPOLL)
|
||||
+# include <sys/epoll.h>
|
||||
+#endif
|
||||
|
||||
-#if defined(HAVE_KQUEUE)
|
||||
+#if !defined(_WIN32)
|
||||
# include <sys/types.h>
|
||||
-# include <sys/event.h>
|
||||
# include <sys/time.h>
|
||||
#endif
|
||||
|
||||
-#if defined(HAVE_EPOLL)
|
||||
-# include <sys/epoll.h>
|
||||
-#endif
|
||||
-
|
||||
+static uv_loop_t main_loop;
|
||||
+static uv_loop_t external_loop;
|
||||
static uv_thread_t embed_thread;
|
||||
static uv_sem_t embed_sem;
|
||||
-static uv_timer_t embed_timer;
|
||||
static uv_async_t embed_async;
|
||||
+static uv_async_t main_async;
|
||||
static volatile int embed_closed;
|
||||
|
||||
-static int embed_timer_called;
|
||||
+static uv_timer_t main_timer;
|
||||
+static int main_timer_called;
|
||||
|
||||
|
||||
-static void embed_thread_runner(void* arg) {
|
||||
+#if defined(_WIN32)
|
||||
+static void embed_thread_poll_win(HANDLE iocp, int timeout) {
|
||||
+ DWORD bytes;
|
||||
+ ULONG_PTR key;
|
||||
+ OVERLAPPED* overlapped;
|
||||
+
|
||||
+ GetQueuedCompletionStatus(iocp,
|
||||
+ &bytes,
|
||||
+ &key,
|
||||
+ &overlapped,
|
||||
+ timeout >= 0 ? timeout : INFINITE);
|
||||
+
|
||||
+ /* Give the event back so the loop can deal with it. */
|
||||
+ if (overlapped != NULL)
|
||||
+ PostQueuedCompletionStatus(iocp,
|
||||
+ bytes,
|
||||
+ key,
|
||||
+ overlapped);
|
||||
+}
|
||||
+#else
|
||||
+static void embed_thread_poll_unix(int fd, int timeout) {
|
||||
int r;
|
||||
- int fd;
|
||||
+ do {
|
||||
+#if defined(HAVE_EPOLL)
|
||||
+ struct epoll_event ev;
|
||||
+ r = epoll_wait(fd, &ev, 1, timeout);
|
||||
+#else
|
||||
+ struct timeval tv;
|
||||
+ if (timeout >= 0) {
|
||||
+ tv.tv_sec = timeout / 1000;
|
||||
+ tv.tv_usec = (timeout % 1000) * 1000;
|
||||
+ }
|
||||
+ fd_set readset;
|
||||
+ FD_ZERO(&readset);
|
||||
+ FD_SET(fd, &readset);
|
||||
+ r = select(fd + 1, &readset, NULL, NULL, timeout >= 0 ? &tv : NULL);
|
||||
+#endif
|
||||
+ } while (r == -1 && errno == EINTR);
|
||||
+}
|
||||
+#endif /* !_WIN32 */
|
||||
+
|
||||
+
|
||||
+static void embed_thread_runner(void* arg) {
|
||||
int timeout;
|
||||
|
||||
- while (!embed_closed) {
|
||||
- fd = uv_backend_fd(uv_default_loop());
|
||||
- timeout = uv_backend_timeout(uv_default_loop());
|
||||
-
|
||||
- do {
|
||||
-#if defined(HAVE_KQUEUE)
|
||||
- struct timespec ts;
|
||||
- ts.tv_sec = timeout / 1000;
|
||||
- ts.tv_nsec = (timeout % 1000) * 1000000;
|
||||
- r = kevent(fd, NULL, 0, NULL, 0, &ts);
|
||||
-#elif defined(HAVE_EPOLL)
|
||||
- {
|
||||
- struct epoll_event ev;
|
||||
- r = epoll_wait(fd, &ev, 1, timeout);
|
||||
- }
|
||||
+ do {
|
||||
+ timeout = uv_backend_timeout(&main_loop);
|
||||
+
|
||||
+#if defined(_WIN32)
|
||||
+ embed_thread_poll_win(main_loop.iocp, timeout);
|
||||
+#else
|
||||
+ embed_thread_poll_unix(uv_backend_fd(&main_loop), timeout);
|
||||
#endif
|
||||
- } while (r == -1 && errno == EINTR);
|
||||
+
|
||||
uv_async_send(&embed_async);
|
||||
+
|
||||
uv_sem_wait(&embed_sem);
|
||||
- }
|
||||
+ } while (!embed_closed);
|
||||
}
|
||||
|
||||
|
||||
static void embed_cb(uv_async_t* async) {
|
||||
- uv_run(uv_default_loop(), UV_RUN_ONCE);
|
||||
+ /* Run tasks in main loop */
|
||||
+ uv_run(&main_loop, UV_RUN_NOWAIT);
|
||||
|
||||
+ /* Tell embed thread to continue polling */
|
||||
uv_sem_post(&embed_sem);
|
||||
}
|
||||
|
||||
|
||||
-static void embed_timer_cb(uv_timer_t* timer) {
|
||||
- embed_timer_called++;
|
||||
+static void main_timer_cb(uv_timer_t* timer) {
|
||||
+ main_timer_called++;
|
||||
embed_closed = 1;
|
||||
|
||||
uv_close((uv_handle_t*) &embed_async, NULL);
|
||||
+ uv_close((uv_handle_t*) &main_async, NULL);
|
||||
}
|
||||
-#endif
|
||||
|
||||
|
||||
-TEST_IMPL(embed) {
|
||||
-#if defined(HAVE_KQUEUE) || defined(HAVE_EPOLL)
|
||||
- uv_loop_t external;
|
||||
-
|
||||
- ASSERT(0 == uv_loop_init(&external));
|
||||
+static void init_loops(void) {
|
||||
+ ASSERT_EQ(0, uv_loop_init(&main_loop));
|
||||
+ ASSERT_EQ(0, uv_loop_init(&external_loop));
|
||||
|
||||
- embed_timer_called = 0;
|
||||
+ main_timer_called = 0;
|
||||
embed_closed = 0;
|
||||
|
||||
- uv_async_init(&external, &embed_async, embed_cb);
|
||||
+ uv_async_init(&external_loop, &embed_async, embed_cb);
|
||||
|
||||
- /* Start timer in default loop */
|
||||
- uv_timer_init(uv_default_loop(), &embed_timer);
|
||||
- uv_timer_start(&embed_timer, embed_timer_cb, 250, 0);
|
||||
+ /* Create a dummy async for main loop otherwise backend timeout will
|
||||
+ always be 0 */
|
||||
+ uv_async_init(&main_loop, &main_async, embed_cb);
|
||||
|
||||
- /* Start worker that will interrupt external loop */
|
||||
+ /* Start worker that will poll main loop and interrupt external loop */
|
||||
uv_sem_init(&embed_sem, 0);
|
||||
uv_thread_create(&embed_thread, embed_thread_runner, NULL);
|
||||
+}
|
||||
|
||||
- /* But run external loop */
|
||||
- uv_run(&external, UV_RUN_DEFAULT);
|
||||
+
|
||||
+static void run_loop(void) {
|
||||
+ /* Run external loop */
|
||||
+ uv_run(&external_loop, UV_RUN_DEFAULT);
|
||||
|
||||
uv_thread_join(&embed_thread);
|
||||
- uv_loop_close(&external);
|
||||
+ uv_sem_destroy(&embed_sem);
|
||||
+ uv_loop_close(&external_loop);
|
||||
+ uv_loop_close(&main_loop);
|
||||
+}
|
||||
|
||||
- ASSERT(embed_timer_called == 1);
|
||||
-#endif
|
||||
+
|
||||
+TEST_IMPL(embed) {
|
||||
+ init_loops();
|
||||
+
|
||||
+ /* Start timer in main loop */
|
||||
+ uv_timer_init(&main_loop, &main_timer);
|
||||
+ uv_timer_start(&main_timer, main_timer_cb, 250, 0);
|
||||
+
|
||||
+ run_loop();
|
||||
+ ASSERT_EQ(main_timer_called, 1);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static uv_timer_t external_timer;
|
||||
+
|
||||
+
|
||||
+static void external_timer_cb(uv_timer_t* timer) {
|
||||
+ /* Start timer in main loop */
|
||||
+ uv_timer_init(&main_loop, &main_timer);
|
||||
+ uv_timer_start(&main_timer, main_timer_cb, 250, 0);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+TEST_IMPL(embed_with_external_timer) {
|
||||
+ init_loops();
|
||||
+
|
||||
+ /* Interrupt embed polling when a handle is started */
|
||||
+ ASSERT_EQ(0, uv_loop_configure(&main_loop, UV_LOOP_INTERRUPT_ON_IO_CHANGE));
|
||||
+
|
||||
+ /* Start timer in external loop, whose callback will not interrupt the
|
||||
+ polling in embed thread */
|
||||
+ uv_timer_init(&external_loop, &external_timer);
|
||||
+ uv_timer_start(&external_timer, external_timer_cb, 100, 0);
|
||||
+
|
||||
+ run_loop();
|
||||
+ ASSERT_EQ(main_timer_called, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
diff --git a/deps/uv/test/test-list.h b/deps/uv/test/test-list.h
|
||||
index a43edf1a4a9b0932ec73b8edaca0f676ecf3ccfa..199402e31406cf8ba360d54769461bb5285011ee 100644
|
||||
--- a/deps/uv/test/test-list.h
|
||||
+++ b/deps/uv/test/test-list.h
|
||||
@@ -263,6 +263,7 @@ TEST_DECLARE (process_priority)
|
||||
TEST_DECLARE (has_ref)
|
||||
TEST_DECLARE (active)
|
||||
TEST_DECLARE (embed)
|
||||
+TEST_DECLARE (embed_with_external_timer)
|
||||
TEST_DECLARE (async)
|
||||
TEST_DECLARE (async_null_cb)
|
||||
TEST_DECLARE (eintr_handling)
|
||||
@@ -860,6 +861,7 @@ TASK_LIST_START
|
||||
TEST_ENTRY (active)
|
||||
|
||||
TEST_ENTRY (embed)
|
||||
+ TEST_ENTRY (embed_with_external_timer)
|
||||
|
||||
TEST_ENTRY (async)
|
||||
TEST_ENTRY (async_null_cb)
|
|
@ -1,59 +0,0 @@
|
|||
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 606083c87de5790d7e66fc34aeaae9a58acb8ef4..ca9568c58b1ccd554318f5deb27d2b4e80f08a28 100644
|
||||
--- a/deps/uv/include/uv.h
|
||||
+++ b/deps/uv/include/uv.h
|
||||
@@ -1805,6 +1805,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 71e9c525c4a77b8b5322e8516c58329100a8d951..a6425294086ff2f1435fdd6866380d3aaaf68200 100644
|
||||
--- a/deps/uv/src/unix/core.c
|
||||
+++ b/deps/uv/src/unix/core.c
|
||||
@@ -906,8 +906,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;
|
||||
@@ -942,8 +945,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);
|
||||
+ }
|
||||
}
|
||||
|
||||
|
||||
@@ -960,6 +966,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);
|
||||
}
|
||||
|
||||
|
|
@ -8,7 +8,7 @@ Now that uv__cloexec_fcntl() is simplified
|
|||
maintaining duplicate code paths for the same thing.
|
||||
|
||||
diff --git a/deps/uv/src/unix/core.c b/deps/uv/src/unix/core.c
|
||||
index 6cd519ad5b3e7af8f5c71b18a59b88458a233f15..8c30802ad15316a8ec20ecedfb5123174d74276b 100644
|
||||
index a87b96cfc1dfdc88fa712a4fa991320ff28f2dcd..7cd3a2a954ff7d70e6ba7a6f7538648841bc54b2 100644
|
||||
--- a/deps/uv/src/unix/core.c
|
||||
+++ b/deps/uv/src/unix/core.c
|
||||
@@ -597,20 +597,6 @@ int uv__nonblock_ioctl(int fd, int set) {
|
||||
|
|
|
@ -7,7 +7,7 @@ FD_CLOEXEC is the only defined flag for fcntl(F_SETFD) so don't bother
|
|||
getting the status of that flag first with fcntl(F_GETFD), just set it.
|
||||
|
||||
diff --git a/deps/uv/src/unix/core.c b/deps/uv/src/unix/core.c
|
||||
index a6425294086ff2f1435fdd6866380d3aaaf68200..6cd519ad5b3e7af8f5c71b18a59b88458a233f15 100644
|
||||
index 71e9c525c4a77b8b5322e8516c58329100a8d951..a87b96cfc1dfdc88fa712a4fa991320ff28f2dcd 100644
|
||||
--- a/deps/uv/src/unix/core.c
|
||||
+++ b/deps/uv/src/unix/core.c
|
||||
@@ -649,21 +649,9 @@ int uv__cloexec_fcntl(int fd, int set) {
|
||||
|
|
|
@ -322,6 +322,9 @@ NodeBindings::NodeBindings(BrowserEnvironment browser_env)
|
|||
} else {
|
||||
uv_loop_ = uv_default_loop();
|
||||
}
|
||||
|
||||
// Interrupt embed polling when a handle is started.
|
||||
uv_loop_configure(uv_loop_, UV_LOOP_INTERRUPT_ON_IO_CHANGE);
|
||||
}
|
||||
|
||||
NodeBindings::~NodeBindings() {
|
||||
|
|
|
@ -38,22 +38,9 @@ void NodeBindingsLinux::RunMessageLoop() {
|
|||
|
||||
handle_ = handle;
|
||||
|
||||
// Get notified when libuv's watcher queue changes.
|
||||
uv_loop_->data = this;
|
||||
uv_loop_->on_watcher_queue_updated = OnWatcherQueueChanged;
|
||||
|
||||
NodeBindings::RunMessageLoop();
|
||||
}
|
||||
|
||||
// static
|
||||
void NodeBindingsLinux::OnWatcherQueueChanged(uv_loop_t* loop) {
|
||||
NodeBindingsLinux* self = static_cast<NodeBindingsLinux*>(loop->data);
|
||||
|
||||
// We need to break the io polling in the epoll thread when loop's watcher
|
||||
// queue changes, otherwise new events cannot be notified.
|
||||
self->WakeupEmbedThread();
|
||||
}
|
||||
|
||||
void NodeBindingsLinux::PollEvents() {
|
||||
int timeout = uv_backend_timeout(uv_loop_);
|
||||
|
||||
|
|
|
@ -19,9 +19,6 @@ class NodeBindingsLinux : public NodeBindings {
|
|||
void RunMessageLoop() override;
|
||||
|
||||
private:
|
||||
// Called when uv's watcher queue changes.
|
||||
static void OnWatcherQueueChanged(uv_loop_t* loop);
|
||||
|
||||
void PollEvents() override;
|
||||
|
||||
// Epoll to poll for uv's backend fd.
|
||||
|
|
|
@ -38,22 +38,9 @@ void NodeBindingsMac::RunMessageLoop() {
|
|||
|
||||
handle_ = handle;
|
||||
|
||||
// Get notified when libuv's watcher queue changes.
|
||||
uv_loop_->data = this;
|
||||
uv_loop_->on_watcher_queue_updated = OnWatcherQueueChanged;
|
||||
|
||||
NodeBindings::RunMessageLoop();
|
||||
}
|
||||
|
||||
// static
|
||||
void NodeBindingsMac::OnWatcherQueueChanged(uv_loop_t* loop) {
|
||||
NodeBindingsMac* self = static_cast<NodeBindingsMac*>(loop->data);
|
||||
|
||||
// We need to break the io polling in the kqueue thread when loop's watcher
|
||||
// queue changes, otherwise new events cannot be notified.
|
||||
self->WakeupEmbedThread();
|
||||
}
|
||||
|
||||
void NodeBindingsMac::PollEvents() {
|
||||
struct timeval tv;
|
||||
int timeout = uv_backend_timeout(uv_loop_);
|
||||
|
|
|
@ -19,9 +19,6 @@ class NodeBindingsMac : public NodeBindings {
|
|||
void RunMessageLoop() override;
|
||||
|
||||
private:
|
||||
// Called when uv's watcher queue changes.
|
||||
static void OnWatcherQueueChanged(uv_loop_t* loop);
|
||||
|
||||
void PollEvents() override;
|
||||
|
||||
// uv's backend fd.
|
||||
|
|
Загрузка…
Ссылка в новой задаче