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 <info@bnoordhuis.nl>
This commit is contained in:
Saúl Ibarra Corretgé 2015-05-27 11:37:34 +02:00
parent 3ceb260c65
commit 1816dbc85f
2 changed files with 10 additions and 3 deletions

View File

@ -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 */

View File

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