From b30a3e677b144afa19143490e9ffc9f882cb4722 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=BAl=20Ibarra=20Corretg=C3=A9?= Date: Wed, 14 Jan 2015 09:24:46 +0100 Subject: [PATCH] unix, windows: set non-block mode in uv_poll_init libuv requires that the socket/fd is in non-blocking mode, so do it internally so the user doesn't need to write platform specific code to do so. This also makes the API consistent with uv_{tcp,udp,pipe}_open, since it's not required to pass the fd in non-blocking mode there either. PR-URL: https://github.com/libuv/libuv/pull/136 Reviewed-By: Ben Noordhuis --- docs/src/poll.rst | 4 ++++ src/unix/poll.c | 6 ++++++ src/win/poll.c | 5 +++++ test/test-poll.c | 27 +++------------------------ 4 files changed, 18 insertions(+), 24 deletions(-) diff --git a/docs/src/poll.rst b/docs/src/poll.rst index f3484225..907cb1a6 100644 --- a/docs/src/poll.rst +++ b/docs/src/poll.rst @@ -70,11 +70,15 @@ API Initialize the handle using a file descriptor. + .. versionchanged:: 1.2.2 the file descriptor is set to non-blocking mode. + .. c:function:: int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle, uv_os_sock_t socket) Initialize the handle using a socket descriptor. On Unix this is identical to :c:func:`uv_poll_init`. On windows it takes a SOCKET handle. + .. versionchanged:: 1.2.2 the socket is set to non-blocking mode. + .. c:function:: int uv_poll_start(uv_poll_t* handle, int events, uv_poll_cb cb) Starts polling the file descriptor. `events` is a bitmask consisting made up diff --git a/src/unix/poll.c b/src/unix/poll.c index a34a8d1e..37da3b95 100644 --- a/src/unix/poll.c +++ b/src/unix/poll.c @@ -51,6 +51,12 @@ static void uv__poll_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) { int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd) { + int err; + + err = uv__nonblock(fd, 1); + if (err) + return err; + uv__handle_init(loop, (uv_handle_t*) handle, UV_POLL); uv__io_init(&handle->io_watcher, uv__poll_io, fd); handle->poll_cb = NULL; diff --git a/src/win/poll.c b/src/win/poll.c index 578d9fff..4d8e1f99 100644 --- a/src/win/poll.c +++ b/src/win/poll.c @@ -505,6 +505,11 @@ int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle, int len; SOCKET peer_socket, base_socket; DWORD bytes; + DWORD yes = 1; + + /* Set the socket to nonblocking mode */ + if (ioctlsocket(socket, FIONBIO, &yes) == SOCKET_ERROR) + return uv_translate_sys_error(WSAGetLastError()); /* Try to obtain a base handle for the socket. This increases this chances */ /* that we find an AFD handle and are able to use the fast poll mechanism. */ diff --git a/test/test-poll.c b/test/test-poll.c index 46587623..be8b00c3 100644 --- a/test/test-poll.c +++ b/test/test-poll.c @@ -22,7 +22,6 @@ #include #ifndef _WIN32 -# include # include # include #endif @@ -86,23 +85,7 @@ static int got_eagain(void) { } -static void set_nonblocking(uv_os_sock_t sock) { - int r; -#ifdef _WIN32 - unsigned long on = 1; - r = ioctlsocket(sock, FIONBIO, &on); - ASSERT(r == 0); -#else - int flags = fcntl(sock, F_GETFL, 0); - ASSERT(flags >= 0); - r = fcntl(sock, F_SETFL, flags | O_NONBLOCK); - ASSERT(r >= 0); -#endif -} - - -static uv_os_sock_t create_nonblocking_bound_socket( - struct sockaddr_in bind_addr) { +static uv_os_sock_t create_bound_socket (struct sockaddr_in bind_addr) { uv_os_sock_t sock; int r; @@ -113,8 +96,6 @@ static uv_os_sock_t create_nonblocking_bound_socket( ASSERT(sock >= 0); #endif - set_nonblocking(sock); - #ifndef _WIN32 { /* Allow reuse of the port. */ @@ -479,8 +460,6 @@ static void server_poll_cb(uv_poll_t* handle, int status, int events) { ASSERT(sock >= 0); #endif - set_nonblocking(sock); - connection_context = create_connection_context(sock, 1); connection_context->events = UV_READABLE | UV_WRITABLE; r = uv_poll_start(&connection_context->poll_handle, @@ -502,7 +481,7 @@ static void start_server(void) { int r; ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - sock = create_nonblocking_bound_socket(addr); + sock = create_bound_socket(addr); context = create_server_context(sock); r = listen(sock, 100); @@ -523,7 +502,7 @@ static void start_client(void) { ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &server_addr)); ASSERT(0 == uv_ip4_addr("0.0.0.0", 0, &addr)); - sock = create_nonblocking_bound_socket(addr); + sock = create_bound_socket(addr); context = create_connection_context(sock, 0); context->events = UV_READABLE | UV_WRITABLE;