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;
}

Reply via email to