From 1816dbc85fef0f3da949dea679e1171f34259f97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=BAl=20Ibarra=20Corretg=C3=A9?= Date: Wed, 27 May 2015 11:37:34 +0200 Subject: [PATCH] unix: make sure UDP send callbacks are asynchronous Fixes: https://github.com/libuv/libuv/issues/301 PR-URL: https://github.com/libuv/libuv/pull/371 Reviewed-By: Ben Noordhuis --- src/unix/internal.h | 3 ++- src/unix/udp.c | 10 ++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/unix/internal.h b/src/unix/internal.h index 31db5e29..c31e5499 100644 --- a/src/unix/internal.h +++ b/src/unix/internal.h @@ -143,7 +143,8 @@ enum { UV_TCP_NODELAY = 0x400, /* Disable Nagle. */ UV_TCP_KEEPALIVE = 0x800, /* Turn on keep-alive. */ UV_TCP_SINGLE_ACCEPT = 0x1000, /* Only accept() when idle. */ - UV_HANDLE_IPV6 = 0x10000 /* Handle is bound to a IPv6 socket. */ + UV_HANDLE_IPV6 = 0x10000, /* Handle is bound to a IPv6 socket. */ + UV_UDP_PROCESSING = 0x20000 /* Handle is running the send callback queue. */ }; /* loop flags */ diff --git a/src/unix/udp.c b/src/unix/udp.c index 2648fd23..a6af40d2 100644 --- a/src/unix/udp.c +++ b/src/unix/udp.c @@ -89,6 +89,9 @@ static void uv__udp_run_completed(uv_udp_t* handle) { uv_udp_send_t* req; QUEUE* q; + assert(!(handle->flags & UV_UDP_PROCESSING)); + handle->flags |= UV_UDP_PROCESSING; + while (!QUEUE_EMPTY(&handle->write_completed_queue)) { q = QUEUE_HEAD(&handle->write_completed_queue); QUEUE_REMOVE(q); @@ -121,6 +124,8 @@ static void uv__udp_run_completed(uv_udp_t* handle) { if (!uv__io_active(&handle->io_watcher, UV__POLLIN)) uv__handle_stop(handle); } + + handle->flags &= ~UV_UDP_PROCESSING; } @@ -410,10 +415,11 @@ int uv__udp_send(uv_udp_send_t* req, QUEUE_INSERT_TAIL(&handle->write_queue, &req->queue); uv__handle_start(handle); - if (empty_queue) + if (empty_queue && !(handle->flags & UV_UDP_PROCESSING)) { uv__udp_sendmsg(handle); - else + } else { uv__io_start(handle->loop, &handle->io_watcher, UV__POLLOUT); + } return 0; }