From f63db009a1e1baf9f1fe7dae39901c7449c66131 Mon Sep 17 00:00:00 2001 From: Martin Sustrik Date: Thu, 28 Jul 2011 16:32:08 +0200 Subject: Different listener implementations simplified Signed-off-by: Martin Sustrik --- src/ipc_listener.cpp | 63 +++---------------- src/tcp_listener.cpp | 171 ++++++++++++-------------------------------------- src/tcp_listener.hpp | 2 +- src/vtcp_listener.cpp | 2 +- 4 files changed, 51 insertions(+), 187 deletions(-) diff --git a/src/ipc_listener.cpp b/src/ipc_listener.cpp index a61ceed..200a2bc 100644 --- a/src/ipc_listener.cpp +++ b/src/ipc_listener.cpp @@ -111,33 +111,17 @@ int zmq::ipc_listener_t::set_address (const char *addr_) if (s == -1) return -1; - // Set the non-blocking flag. - int flag = fcntl (s, F_GETFL, 0); - if (flag == -1) - flag = 0; - rc = fcntl (s, F_SETFL, flag | O_NONBLOCK); - errno_assert (rc != -1); - // Bind the socket to the file path. rc = bind (s, (struct sockaddr*) &addr, addr_len); - if (rc != 0) { - int err = errno; - if (close () != 0) - return -1; - errno = err; + if (rc != 0) return -1; - } + has_file = true; // Listen for incomming connections. rc = listen (s, options.backlog); - if (rc != 0) { - int err = errno; - if (close () != 0) - return -1; - errno = err; + if (rc != 0) return -1; - } return 0; } @@ -164,44 +148,15 @@ int zmq::ipc_listener_t::close () zmq::fd_t zmq::ipc_listener_t::accept () { + // Accept one connection and deal with different failure modes. zmq_assert (s != retired_fd); - - // Accept one incoming connection. fd_t sock = ::accept (s, NULL, NULL); - -#if (defined ZMQ_HAVE_LINUX || defined ZMQ_HAVE_FREEBSD || \ - defined ZMQ_HAVE_OPENBSD || defined ZMQ_HAVE_OSX || \ - defined ZMQ_HAVE_OPENVMS || defined ZMQ_HAVE_NETBSD || \ - defined ZMQ_HAVE_CYGWIN) - if (sock == -1 && - (errno == EAGAIN || errno == EWOULDBLOCK || - errno == EINTR || errno == ECONNABORTED)) - return retired_fd; -#elif (defined ZMQ_HAVE_SOLARIS || defined ZMQ_HAVE_AIX) - if (sock == -1 && - (errno == EWOULDBLOCK || errno == EINTR || - errno == ECONNABORTED || errno == EPROTO)) - return retired_fd; -#elif defined ZMQ_HAVE_HPUX - if (sock == -1 && - (errno == EAGAIN || errno == EWOULDBLOCK || - errno == EINTR || errno == ECONNABORTED || errno == ENOBUFS)) + if (sock == -1) { + errno_assert (errno == EAGAIN || errno == EWOULDBLOCK || + errno == EINTR || errno == ECONNABORTED || errno == EPROTO || + errno == ENOBUFS); return retired_fd; -#elif defined ZMQ_HAVE_QNXNTO - if (sock == -1 && - (errno == EWOULDBLOCK || errno == EINTR || errno == ECONNABORTED)) - return retired_fd; -#endif - - errno_assert (sock != -1); - - // Set to non-blocking mode. - int flags = fcntl (s, F_GETFL, 0); - if (flags == -1) - flags = 0; - int rc = fcntl (sock, F_SETFL, flags | O_NONBLOCK); - errno_assert (rc != -1); - + } return sock; } diff --git a/src/tcp_listener.cpp b/src/tcp_listener.cpp index 1bb6deb..bcb9a37 100644 --- a/src/tcp_listener.cpp +++ b/src/tcp_listener.cpp @@ -107,134 +107,71 @@ void zmq::tcp_listener_t::in_event () send_attach (session, engine, false); } +void zmq::tcp_listener_t::close () +{ + zmq_assert (s != retired_fd); #ifdef ZMQ_HAVE_WINDOWS + int rc = closesocket (s); + wsa_assert (rc != SOCKET_ERROR); +#else + int rc = ::close (s); + errno_assert (rc == 0); +#endif + s = retired_fd; +} int zmq::tcp_listener_t::set_address (const char *addr_) { // Convert the interface into sockaddr_in structure. int rc = resolve_ip_interface (&addr, &addr_len, addr_); if (rc != 0) - return rc; + return -1; // Create a listening socket. s = ::socket (addr.ss_family, SOCK_STREAM, IPPROTO_TCP); +#ifdef ZMQ_HAVE_WINDOWS if (s == INVALID_SOCKET) { wsa_error_to_errno (); return -1; } +#else + if (s == -1) + return -1; +#endif // Allow reusing of the address. int flag = 1; +#ifdef ZMQ_HAVE_WINDOWS rc = setsockopt (s, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (const char*) &flag, sizeof (int)); wsa_assert (rc != SOCKET_ERROR); +#else + rc = setsockopt (s, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof (int)); + errno_assert (rc == 0); +#endif // Bind the socket to the network interface and port. rc = bind (s, (struct sockaddr*) &addr, addr_len); +#ifdef ZMQ_HAVE_WINDOWS if (rc == SOCKET_ERROR) { wsa_error_to_errno (); return -1; } - - // Listen for incomming connections. - rc = listen (s, options.backlog); - if (rc == SOCKET_ERROR) { - wsa_error_to_errno (); - return -1; - } - - return 0; -} - -int zmq::tcp_listener_t::close () -{ - zmq_assert (s != retired_fd); - int rc = closesocket (s); - wsa_assert (rc != SOCKET_ERROR); - s = retired_fd; - return 0; -} - -zmq::fd_t zmq::tcp_listener_t::accept () -{ - zmq_assert (s != retired_fd); - - // Accept one incoming connection. - fd_t sock = ::accept (s, NULL, NULL); - if (sock == INVALID_SOCKET && - (WSAGetLastError () == WSAEWOULDBLOCK || - WSAGetLastError () == WSAECONNRESET)) - return retired_fd; - - zmq_assert (sock != INVALID_SOCKET); - - // Set to non-blocking mode. - unsigned long argp = 1; - int rc = ioctlsocket (sock, FIONBIO, &argp); - wsa_assert (rc != SOCKET_ERROR); - - return sock; -} - #else - -int zmq::tcp_listener_t::set_address (const char *addr_) -{ - // Resolve the sockaddr to bind to. - int rc = resolve_ip_interface (&addr, &addr_len, addr_); if (rc != 0) return -1; - - // Create a listening socket. - s = ::socket (addr.ss_family, SOCK_STREAM, IPPROTO_TCP); - if (s == -1) - return -1; - - // Allow reusing of the address. - int flag = 1; - rc = setsockopt (s, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof (int)); - errno_assert (rc == 0); - - // Bind the socket to the network interface and port. - rc = bind (s, (struct sockaddr*) &addr, addr_len); - if (rc != 0) { - int err = errno; - if (close () != 0) - return -1; - errno = err; - return -1; - } +#endif // Listen for incomming connections. rc = listen (s, options.backlog); - if (rc != 0) { - int err = errno; - if (close () != 0) - return -1; - errno = err; +#ifdef ZMQ_HAVE_WINDOWS + if (rc == SOCKET_ERROR) { + wsa_error_to_errno (); return -1; } - - return 0; -} - -int zmq::tcp_listener_t::close () -{ - zmq_assert (s != retired_fd); - int rc = ::close (s); +#else if (rc != 0) return -1; - s = retired_fd; - -#ifndef ZMQ_HAVE_OPENVMS - // If there's an underlying UNIX domain socket, get rid of the file it - // is associated with. - struct sockaddr_un *su = (struct sockaddr_un*) &addr; - if (AF_UNIX == su->sun_family && has_file) { - rc = ::unlink(su->sun_path); - if (rc != 0) - return -1; - } #endif return 0; @@ -242,51 +179,23 @@ int zmq::tcp_listener_t::close () zmq::fd_t zmq::tcp_listener_t::accept () { + // Accept one connection and deal with different failure modes. zmq_assert (s != retired_fd); - - // Accept one incoming connection. fd_t sock = ::accept (s, NULL, NULL); - -#if (defined ZMQ_HAVE_LINUX || defined ZMQ_HAVE_FREEBSD || \ - defined ZMQ_HAVE_OPENBSD || defined ZMQ_HAVE_OSX || \ - defined ZMQ_HAVE_OPENVMS || defined ZMQ_HAVE_NETBSD || \ - defined ZMQ_HAVE_CYGWIN) - if (sock == -1 && - (errno == EAGAIN || errno == EWOULDBLOCK || - errno == EINTR || errno == ECONNABORTED)) - return retired_fd; -#elif (defined ZMQ_HAVE_SOLARIS || defined ZMQ_HAVE_AIX) - if (sock == -1 && - (errno == EWOULDBLOCK || errno == EINTR || - errno == ECONNABORTED || errno == EPROTO)) - return retired_fd; -#elif defined ZMQ_HAVE_HPUX - if (sock == -1 && - (errno == EAGAIN || errno == EWOULDBLOCK || - errno == EINTR || errno == ECONNABORTED || errno == ENOBUFS)) - return retired_fd; -#elif defined ZMQ_HAVE_QNXNTO - if (sock == -1 && - (errno == EWOULDBLOCK || errno == EINTR || errno == ECONNABORTED)) +#ifdef ZMQ_HAVE_WINDOWS + if (sock == INVALID_SOCKET) + wsa_assert (WSAGetLastError () == WSAEWOULDBLOCK || + WSAGetLastError () == WSAECONNRESET); return retired_fd; -#endif - - errno_assert (sock != -1); - - // Set to non-blocking mode. -#ifdef ZMQ_HAVE_OPENVMS - int flags = 1; - int rc = ioctl (sock, FIONBIO, &flags); - errno_assert (rc != -1); + } #else - int flags = fcntl (s, F_GETFL, 0); - if (flags == -1) - flags = 0; - int rc = fcntl (sock, F_SETFL, flags | O_NONBLOCK); - errno_assert (rc != -1); + if (sock == -1) { + errno_assert (errno == EAGAIN || errno == EWOULDBLOCK || + errno == EINTR || errno == ECONNABORTED || errno == EPROTO || + errno == ENOBUFS); + return retired_fd; + } #endif - return sock; } -#endif diff --git a/src/tcp_listener.hpp b/src/tcp_listener.hpp index 857317a..69fde37 100644 --- a/src/tcp_listener.hpp +++ b/src/tcp_listener.hpp @@ -51,7 +51,7 @@ namespace zmq void in_event (); // Close the listening socket. - int close (); + void close (); // Accept the new connection. Returns the file descriptor of the // newly created connection. The function may return retired_fd diff --git a/src/vtcp_listener.cpp b/src/vtcp_listener.cpp index 8fbefb2..93d9e69 100644 --- a/src/vtcp_listener.cpp +++ b/src/vtcp_listener.cpp @@ -69,7 +69,7 @@ int zmq::vtcp_listener_t::set_address (const char *addr_) uint16_t port = (uint16_t) atoi (port_str.c_str ()); uint32_t subport = (uint32_t) atoi (subport_str.c_str ()); - // Srart listening. + // Start listening. s = vtcp_bind (port, subport); if (s == retired_fd) return -1; -- cgit v1.2.3