From cf05c5f0d6af680e535743b262a8701bd96a05f5 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Fri, 27 Jul 2012 15:13:27 +0200 Subject: [PATCH] Raise UV_ECANCELED on premature close. Set the error code to the more appropriate UV_ECANCELED instead of UV_EINTR when the handle is closed and there are in-flight requests. --- include/uv.h | 5 +++-- src/unix/stream.c | 6 +++--- src/win/pipe.c | 2 +- src/win/tcp.c | 8 ++------ src/win/tty.c | 2 +- test/benchmark-udp-packet-storm.c | 2 +- test/test-shutdown-close.c | 4 ++-- test/test-tcp-close-while-connecting.c | 2 +- 8 files changed, 14 insertions(+), 17 deletions(-) diff --git a/include/uv.h b/include/uv.h index 39d114a6c..d6646ccdc 100644 --- a/include/uv.h +++ b/include/uv.h @@ -127,7 +127,8 @@ extern "C" { XX( 54, ENOSPC, "no space left on device") \ XX( 55, EIO, "i/o error") \ XX( 56, EROFS, "read-only file system" ) \ - XX( 57, ENODEV, "no such device" ) + XX( 57, ENODEV, "no such device" ) \ + XX( 58, ECANCELED, "operation canceled" ) #define UV_ERRNO_GEN(val, name, s) UV_##name = val, @@ -436,7 +437,7 @@ UV_EXTERN void uv_walk(uv_loop_t* loop, uv_walk_cb walk_cb, void* arg); * * In-progress requests, like uv_connect_t or uv_write_t, are cancelled and * have their callbacks called asynchronously with status=-1 and the error code - * set to UV_EINTR. + * set to UV_ECANCELED. */ UV_EXTERN void uv_close(uv_handle_t* handle, uv_close_cb close_cb); diff --git a/src/unix/stream.c b/src/unix/stream.c index 8c33ee09c..fd024ed38 100644 --- a/src/unix/stream.c +++ b/src/unix/stream.c @@ -120,7 +120,7 @@ void uv__stream_destroy(uv_stream_t* stream) { if (stream->connect_req) { uv__req_unregister(stream->loop, stream->connect_req); - uv__set_artificial_error(stream->loop, UV_EINTR); + uv__set_artificial_error(stream->loop, UV_ECANCELED); stream->connect_req->cb(stream->connect_req, -1); stream->connect_req = NULL; } @@ -136,7 +136,7 @@ void uv__stream_destroy(uv_stream_t* stream) { free(req->bufs); if (req->cb) { - uv__set_artificial_error(req->handle->loop, UV_EINTR); + uv__set_artificial_error(req->handle->loop, UV_ECANCELED); req->cb(req, -1); } } @@ -156,7 +156,7 @@ void uv__stream_destroy(uv_stream_t* stream) { if (stream->shutdown_req) { uv__req_unregister(stream->loop, stream->shutdown_req); - uv__set_artificial_error(stream->loop, UV_EINTR); + uv__set_artificial_error(stream->loop, UV_ECANCELED); stream->shutdown_req->cb(stream->shutdown_req, -1); stream->shutdown_req = NULL; } diff --git a/src/win/pipe.c b/src/win/pipe.c index 77a1c7b75..5da14eaa9 100644 --- a/src/win/pipe.c +++ b/src/win/pipe.c @@ -300,7 +300,7 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) { /* Already closing. Cancel the shutdown. */ if (req->cb) { - uv__set_sys_error(loop, WSAEINTR); + uv__set_artificial_error(loop, UV_ECANCELED); req->cb(req, -1); } diff --git a/src/win/tcp.c b/src/win/tcp.c index e13c0f3df..2a25358d4 100644 --- a/src/win/tcp.c +++ b/src/win/tcp.c @@ -157,7 +157,6 @@ int uv_tcp_init(uv_loop_t* loop, uv_tcp_t* handle) { void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) { int status; - int sys_error; unsigned int i; uv_tcp_accept_t* req; @@ -169,19 +168,16 @@ void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) { if (handle->flags & UV_HANDLE_CLOSING) { status = -1; - sys_error = WSAEINTR; + uv__set_artificial_error(loop, UV_ECANCELED); } else if (shutdown(handle->socket, SD_SEND) != SOCKET_ERROR) { status = 0; handle->flags |= UV_HANDLE_SHUT; } else { status = -1; - sys_error = WSAGetLastError(); + uv__set_sys_error(loop, WSAGetLastError()); } if (handle->shutdown_req->cb) { - if (status == -1) { - uv__set_sys_error(loop, sys_error); - } handle->shutdown_req->cb(handle->shutdown_req, status); } diff --git a/src/win/tty.c b/src/win/tty.c index 340bcdcb3..66103e6b6 100644 --- a/src/win/tty.c +++ b/src/win/tty.c @@ -1751,7 +1751,7 @@ void uv_tty_endgame(uv_loop_t* loop, uv_tty_t* handle) { /* TTY shutdown is really just a no-op */ if (handle->shutdown_req->cb) { if (handle->flags & UV_HANDLE_CLOSING) { - uv__set_sys_error(loop, WSAEINTR); + uv__set_artificial_error(loop, UV_ECANCELED); handle->shutdown_req->cb(handle->shutdown_req, -1); } else { handle->shutdown_req->cb(handle->shutdown_req, 0); diff --git a/test/benchmark-udp-packet-storm.c b/test/benchmark-udp-packet-storm.c index 594128705..9842e4cea 100644 --- a/test/benchmark-udp-packet-storm.c +++ b/test/benchmark-udp-packet-storm.c @@ -91,7 +91,7 @@ static void recv_cb(uv_udp_t* handle, return; if (nread == -1) { - ASSERT(uv_last_error(loop).code == UV_EINTR); /* FIXME change error code */ + ASSERT(uv_last_error(loop).code == UV_ECANCELED); return; } diff --git a/test/test-shutdown-close.c b/test/test-shutdown-close.c index eabbefc60..6ce46b245 100644 --- a/test/test-shutdown-close.c +++ b/test/test-shutdown-close.c @@ -37,9 +37,9 @@ static int close_cb_called = 0; static void shutdown_cb(uv_shutdown_t* req, int status) { + int err = uv_last_error(uv_default_loop()).code; ASSERT(req == &shutdown_req); - ASSERT(status == 0 || - (status == -1 && uv_last_error(uv_default_loop()).code == UV_EINTR)); + ASSERT(status == 0 || (status == -1 && err == UV_ECANCELED)); shutdown_cb_called++; } diff --git a/test/test-tcp-close-while-connecting.c b/test/test-tcp-close-while-connecting.c index 93e331d6d..90471ecac 100644 --- a/test/test-tcp-close-while-connecting.c +++ b/test/test-tcp-close-while-connecting.c @@ -38,7 +38,7 @@ static void close_cb(uv_handle_t* handle) { static void connect_cb(uv_connect_t* req, int status) { ASSERT(status == -1); - ASSERT(uv_last_error(req->handle->loop).code == UV_EINTR); + ASSERT(uv_last_error(req->handle->loop).code == UV_ECANCELED); uv_timer_stop(&timer2_handle); connect_cb_called++; }