unix: delay signal handling until after normal i/o
It was reported that some node.js tests fail on AIX because the exit event sometimes comes before the final stdio output of a child process. Work around that by deferring the signal watcher that is used for process management until after the dispatch of regular i/o watchers. Fixes: https://github.com/libuv/libuv/issues/610 PR-URL: https://github.com/libuv/libuv/pull/611 Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
This commit is contained in:
parent
572d31599f
commit
4a5b3f982e
@ -118,6 +118,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
uv__io_t* w;
|
||||
uint64_t base;
|
||||
uint64_t diff;
|
||||
int have_signals;
|
||||
int nevents;
|
||||
int count;
|
||||
int nfds;
|
||||
@ -225,6 +226,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
goto update_timeout;
|
||||
}
|
||||
|
||||
have_signals = 0;
|
||||
nevents = 0;
|
||||
|
||||
assert(loop->watchers != NULL);
|
||||
@ -255,13 +257,26 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
continue;
|
||||
}
|
||||
|
||||
w->cb(loop, w, pe->revents);
|
||||
/* Run signal watchers last. This also affects child process watchers
|
||||
* because those are implemented in terms of signal watchers.
|
||||
*/
|
||||
if (w == &loop->signal_io_watcher)
|
||||
have_signals = 1;
|
||||
else
|
||||
w->cb(loop, w, pe->revents);
|
||||
|
||||
nevents++;
|
||||
}
|
||||
|
||||
if (have_signals != 0)
|
||||
loop->signal_io_watcher.cb(loop, &loop->signal_io_watcher, POLLIN);
|
||||
|
||||
loop->watchers[loop->nwatchers] = NULL;
|
||||
loop->watchers[loop->nwatchers + 1] = NULL;
|
||||
|
||||
if (have_signals != 0)
|
||||
return; /* Event loop should cycle now so don't poll again. */
|
||||
|
||||
if (nevents != 0) {
|
||||
if (nfds == ARRAY_SIZE(events) && --count != 0) {
|
||||
/* Poll for more events but don't block this time. */
|
||||
|
||||
@ -78,6 +78,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
sigset_t set;
|
||||
uint64_t base;
|
||||
uint64_t diff;
|
||||
int have_signals;
|
||||
int filter;
|
||||
int fflags;
|
||||
int count;
|
||||
@ -192,6 +193,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
goto update_timeout;
|
||||
}
|
||||
|
||||
have_signals = 0;
|
||||
nevents = 0;
|
||||
|
||||
assert(loop->watchers != NULL);
|
||||
@ -265,12 +267,26 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
if (revents == 0)
|
||||
continue;
|
||||
|
||||
w->cb(loop, w, revents);
|
||||
/* Run signal watchers last. This also affects child process watchers
|
||||
* because those are implemented in terms of signal watchers.
|
||||
*/
|
||||
if (w == &loop->signal_io_watcher)
|
||||
have_signals = 1;
|
||||
else
|
||||
w->cb(loop, w, revents);
|
||||
|
||||
nevents++;
|
||||
}
|
||||
|
||||
if (have_signals != 0)
|
||||
loop->signal_io_watcher.cb(loop, &loop->signal_io_watcher, POLLIN);
|
||||
|
||||
loop->watchers[loop->nwatchers] = NULL;
|
||||
loop->watchers[loop->nwatchers + 1] = NULL;
|
||||
|
||||
if (have_signals != 0)
|
||||
return; /* Event loop should cycle now so don't poll again. */
|
||||
|
||||
if (nevents != 0) {
|
||||
if (nfds == ARRAY_SIZE(events) && --count != 0) {
|
||||
/* Poll for more events but don't block this time. */
|
||||
|
||||
@ -188,6 +188,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
sigset_t sigset;
|
||||
uint64_t sigmask;
|
||||
uint64_t base;
|
||||
int have_signals;
|
||||
int nevents;
|
||||
int count;
|
||||
int nfds;
|
||||
@ -315,6 +316,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
goto update_timeout;
|
||||
}
|
||||
|
||||
have_signals = 0;
|
||||
nevents = 0;
|
||||
|
||||
assert(loop->watchers != NULL);
|
||||
@ -369,13 +371,27 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
pe->events |= w->pevents & (POLLIN | POLLOUT);
|
||||
|
||||
if (pe->events != 0) {
|
||||
w->cb(loop, w, pe->events);
|
||||
/* Run signal watchers last. This also affects child process watchers
|
||||
* because those are implemented in terms of signal watchers.
|
||||
*/
|
||||
if (w == &loop->signal_io_watcher)
|
||||
have_signals = 1;
|
||||
else
|
||||
w->cb(loop, w, pe->events);
|
||||
|
||||
nevents++;
|
||||
}
|
||||
}
|
||||
|
||||
if (have_signals != 0)
|
||||
loop->signal_io_watcher.cb(loop, &loop->signal_io_watcher, POLLIN);
|
||||
|
||||
loop->watchers[loop->nwatchers] = NULL;
|
||||
loop->watchers[loop->nwatchers + 1] = NULL;
|
||||
|
||||
if (have_signals != 0)
|
||||
return; /* Event loop should cycle now so don't poll again. */
|
||||
|
||||
if (nevents != 0) {
|
||||
if (nfds == ARRAY_SIZE(events) && --count != 0) {
|
||||
/* Poll for more events but don't block this time. */
|
||||
|
||||
@ -140,6 +140,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
unsigned int nfds;
|
||||
unsigned int i;
|
||||
int saved_errno;
|
||||
int have_signals;
|
||||
int nevents;
|
||||
int count;
|
||||
int err;
|
||||
@ -230,6 +231,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
return;
|
||||
}
|
||||
|
||||
have_signals = 0;
|
||||
nevents = 0;
|
||||
|
||||
assert(loop->watchers != NULL);
|
||||
@ -252,7 +254,14 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
if (w == NULL)
|
||||
continue;
|
||||
|
||||
w->cb(loop, w, pe->portev_events);
|
||||
/* Run signal watchers last. This also affects child process watchers
|
||||
* because those are implemented in terms of signal watchers.
|
||||
*/
|
||||
if (w == &loop->signal_io_watcher)
|
||||
have_signals = 1;
|
||||
else
|
||||
w->cb(loop, w, pe->portev_events);
|
||||
|
||||
nevents++;
|
||||
|
||||
if (w != loop->watchers[fd])
|
||||
@ -262,9 +271,16 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
if (w->pevents != 0 && QUEUE_EMPTY(&w->watcher_queue))
|
||||
QUEUE_INSERT_TAIL(&loop->watcher_queue, &w->watcher_queue);
|
||||
}
|
||||
|
||||
if (have_signals != 0)
|
||||
loop->signal_io_watcher.cb(loop, &loop->signal_io_watcher, POLLIN);
|
||||
|
||||
loop->watchers[loop->nwatchers] = NULL;
|
||||
loop->watchers[loop->nwatchers + 1] = NULL;
|
||||
|
||||
if (have_signals != 0)
|
||||
return; /* Event loop should cycle now so don't poll again. */
|
||||
|
||||
if (nevents != 0) {
|
||||
if (nfds == ARRAY_SIZE(events) && --count != 0) {
|
||||
/* Poll for more events but don't block this time. */
|
||||
|
||||
Loading…
Reference in New Issue
Block a user