From d5f3628ad08849a0c978f7d23dc678133ed33c42 Mon Sep 17 00:00:00 2001 From: Martin Sustrik Date: Fri, 29 Jul 2011 09:37:43 +0200 Subject: Different connecters simplified Signed-off-by: Martin Sustrik --- src/tcp_connecter.cpp | 179 +++++++++++--------------------------------------- 1 file changed, 40 insertions(+), 139 deletions(-) (limited to 'src/tcp_connecter.cpp') diff --git a/src/tcp_connecter.cpp b/src/tcp_connecter.cpp index 27e56a1..bca7085 100644 --- a/src/tcp_connecter.cpp +++ b/src/tcp_connecter.cpp @@ -177,8 +177,6 @@ int zmq::tcp_connecter_t::get_new_reconnect_ivl () return this_interval; } -#ifdef ZMQ_HAVE_WINDOWS - int zmq::tcp_connecter_t::set_address (const char *addr_) { return resolve_ip_hostname (&addr, &addr_len, addr_); @@ -190,193 +188,96 @@ int zmq::tcp_connecter_t::open () // Create the 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 - // Set to non-blocking mode. - unsigned long argp = 1; - int rc = ioctlsocket (s, FIONBIO, &argp); - wsa_assert (rc != SOCKET_ERROR); + // Set the socket to non-blocking mode so that we get async connect(). + unblock_socket (s); // Connect to the remote peer. - rc = ::connect (s, (sockaddr*) &addr, addr_len); + int rc = ::connect (s, (struct sockaddr*) &addr, addr_len); // Connect was successfull immediately. if (rc == 0) return 0; // Asynchronous connect was launched. +#ifdef ZMQ_HAVE_WINDOWS if (rc == SOCKET_ERROR && (WSAGetLastError () == WSAEINPROGRESS || WSAGetLastError () == WSAEWOULDBLOCK)) { errno = EAGAIN; return -1; - } - + } wsa_error_to_errno (); +#else + if (rc == -1 && errno == EINPROGRESS) { + errno = EAGAIN; + return -1; + } +#endif return -1; } -int zmq::tcp_connecter_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_connecter_t::connect () { - // Nonblocking connect have finished. Check whether an error occured. + // Async connect have finished. Check whether an error occured. int err = 0; - socklen_t len = sizeof err; +#if defined ZMQ_HAVE_HPUX + int len = sizeof (err); +#else + socklen_t len = sizeof (err); +#endif + int rc = getsockopt (s, SOL_SOCKET, SO_ERROR, (char*) &err, &len); + + // Assert if the error was caused by 0MQ bug. + // Networking problems are OK. No need to assert. +#ifdef ZMQ_HAVE_WINDOWS zmq_assert (rc == 0); if (err != 0) { - - // Assert that the error was caused by the networking problems - // rather than 0MQ bug. if (err == WSAECONNREFUSED || err == WSAETIMEDOUT || err == WSAECONNABORTED || err == WSAEHOSTUNREACH || err == WSAENETUNREACH || err == WSAENETDOWN) return retired_fd; - wsa_assert_no (err); } - - // Return the newly connected socket. - fd_t result = s; - s = retired_fd; - return result; -} - -#else - -int zmq::tcp_connecter_t::set_address (const char *addr_) -{ - return resolve_ip_hostname (&addr, &addr_len, addr_); -} - -int zmq::tcp_connecter_t::open () -{ - zmq_assert (s == retired_fd); - struct sockaddr *sa = (struct sockaddr*) &addr; - - if (AF_UNIX != sa->sa_family) { - - // Create the socket. - s = socket (sa->sa_family, SOCK_STREAM, IPPROTO_TCP); - if (s == -1) - return -1; - - // Set to non-blocking mode. -#ifdef ZMQ_HAVE_OPENVMS - int flags = 1; - int rc = ioctl (s, FIONBIO, &flags); - errno_assert (rc != -1); #else - int flags = fcntl (s, F_GETFL, 0); - if (flags == -1) - flags = 0; - int rc = fcntl (s, F_SETFL, flags | O_NONBLOCK); - errno_assert (rc != -1); -#endif - - // Connect to the remote peer. - rc = ::connect (s, (struct sockaddr*) &addr, addr_len); - - // Connect was successfull immediately. - if (rc == 0) - return 0; - - // Asynchronous connect was launched. - if (rc == -1 && errno == EINPROGRESS) { - errno = EAGAIN; - return -1; - } - - // Error occured. - int err = errno; - close (); - errno = err; - return -1; - } - -#ifndef ZMQ_HAVE_OPENVMS - else { - - // Create the socket. - zmq_assert (AF_UNIX == sa->sa_family); - s = socket (AF_UNIX, SOCK_STREAM, 0); - if (s == -1) - return -1; - - // Set the non-blocking flag. - int flag = fcntl (s, F_GETFL, 0); - if (flag == -1) - flag = 0; - int rc = fcntl (s, F_SETFL, flag | O_NONBLOCK); - errno_assert (rc != -1); - - // Connect to the remote peer. - rc = ::connect (s, (struct sockaddr*) &addr, sizeof (sockaddr_un)); - - // Connect was successfull immediately. - if (rc == 0) - return 0; - - // Error occured. - int err = errno; - close (); - errno = err; - return -1; - } -#endif - - zmq_assert (false); - return -1; -} - -int zmq::tcp_connecter_t::close () -{ - zmq_assert (s != retired_fd); - int rc = ::close (s); - if (rc != 0) - return -1; - s = retired_fd; - return 0; -} -zmq::fd_t zmq::tcp_connecter_t::connect () -{ // Following code should handle both Berkeley-derived socket // implementations and Solaris. - int err = 0; -#if defined ZMQ_HAVE_HPUX - int len = sizeof (err); -#else - socklen_t len = sizeof (err); -#endif - int rc = getsockopt (s, SOL_SOCKET, SO_ERROR, (char*) &err, &len); if (rc == -1) err = errno; if (err != 0) { - - // Assert if the error was caused by 0MQ bug. - // Networking problems are OK. No need to assert. errno = err; errno_assert (errno == ECONNREFUSED || errno == ECONNRESET || errno == ETIMEDOUT || errno == EHOSTUNREACH || errno == ENETUNREACH || errno == ENETDOWN); - return retired_fd; } +#endif + // Return the newly connected socket. fd_t result = s; s = retired_fd; return result; } +void zmq::tcp_connecter_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; +} -- cgit v1.2.3