I just noticed that using libuv 1.30.2 built in Ubuntu 16.04, if I call
'uv_close' on a 'uv_signal_t' which callback is going to be executed in the
same loop iteration, the callback of this 'uv_close' is never executed, no
matter how many times I call `uv_run`, even though it is 'uv_is_closing'.
The attached code illustrates the problem by writing 'uv_pipe_t' with the
read end closed to cause a SIGPIPE. In the write callback I close the
'uv_pipe_t' and a `uv_signal_t' previously started with SIGPIPE. The
'uv_pipe_t' closes, but the 'uv_signal_t' never does.
I also noticed that if I close any other handler after 'uv_run' returns,
then the 'uv_close' callback of the 'uv_signal_t' is called the next time I
call 'uv_run'.
Does any one knows what I might be doing wrong in this code, or a
workaround for this problem?
--
Renato Maia
--
You received this message because you are subscribed to the Google Groups
"libuv" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/libuv/CAB-PuDpUQ%3DHAUKyRfR8Ln9K80z4UKA3kCx4Pn69v47V%2B30RE0A%40mail.gmail.com.
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <uv.h>
static uv_loop_t uvloop;
static uv_signal_t uvsignal;
static uv_pipe_t uvpipe;
static uv_write_t uvwrite;
#define handlename(H) ((H == (uv_handle_t *)&uvsignal) ? "uvsignal" : \
((H == (uv_handle_t *)&uvpipe) ? "uvpipe" : \
"unknown"))
static void onclosed (uv_handle_t *handle)
{
printf("%s:%d: %s(%s)\n", __FILE__, __LINE__, __func__, handlename(handle));
}
static void onsignal (uv_signal_t *signal, int signum)
{
assert(0);
}
static void onwritten (uv_write_t *request, int err)
{
free(request->data);
request->data = NULL;
uv_close((uv_handle_t *)&uvpipe, onclosed);
uv_close((uv_handle_t *)&uvsignal, onclosed);
printf("%s:%d: %s(err=%s)\n", __FILE__, __LINE__, __func__, uv_strerror(err));
}
static void assertclosing (uv_handle_t* handle, void* arg) {
assert(uv_is_closing(handle));
printf("%s:%d: %s(%s)\n", __FILE__, __LINE__, __func__, handlename(handle));
}
int main(int argc, char const *argv[])
{
int err, i;
uv_buf_t bufs[1];
int pipefds[2];
err = uv_loop_init(&uvloop);
assert(err >= 0);
err = uv_signal_init(&uvloop, &uvsignal);
assert(err >= 0);
err = uv_signal_start(&uvsignal, onsignal, SIGPIPE);
assert(err >= 0);
err = pipe(pipefds);
assert(err == 0);
err = uv_pipe_init(&uvloop, &uvpipe, 0);
assert(err >= 0);
err = uv_pipe_open(&uvpipe, pipefds[1]);
assert(err >= 0);
/* write enougth bytes to only complete in 'uv_run' */
uvwrite.data = malloc(1<<24);
memset(uvwrite.data, 'x', 1<<24);
bufs[0].base = uvwrite.data;
bufs[0].len = 1<<24;
err = uv_write(&uvwrite, (uv_stream_t *)&uvpipe, bufs, 1, onwritten);
assert(err >= 0);
/* cause a SIGPIPE on next write in 'uv_run' */
close(pipefds[0]);
for (i = 0; i < 3; ++i) {
err = uv_run(&uvloop, UV_RUN_DEFAULT);
assert(err >= 0);
printf("%s:%d: uv_run()\n", __FILE__, __LINE__);
}
err = uv_loop_close(&uvloop);
if (err == UV_EBUSY) {
uv_walk(&uvloop, assertclosing, NULL);
err = uv_run(&uvloop, UV_RUN_NOWAIT);
if (!err) err = uv_loop_close(&uvloop);
}
assert(err >= 0);
return 0;
}