From 573a1eab4b2df369a23b11576ba23dee4bf9eaae Mon Sep 17 00:00:00 2001 From: KIU Shueng Chuan Date: Fri, 15 Feb 2013 10:45:43 +0800 Subject: [PATCH 1/3] release critical section on failure to create signaler fdpair --- src/signaler.cpp | 46 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/src/signaler.cpp b/src/signaler.cpp index eba0fab6..dd5c1fc6 100644 --- a/src/signaler.cpp +++ b/src/signaler.cpp @@ -279,7 +279,7 @@ int zmq::signaler_t::make_fdpair (fd_t *r_, fd_t *w_) (char *)&tcp_nodelay, sizeof (tcp_nodelay)); wsa_assert (rc != SOCKET_ERROR); - // Bind listening socket to any free local port. + // Bind listening socket to signaler port. struct sockaddr_in addr; memset (&addr, 0, sizeof (addr)); addr.sin_family = AF_INET; @@ -307,15 +307,19 @@ int zmq::signaler_t::make_fdpair (fd_t *r_, fd_t *w_) // Connect writer to the listener. rc = connect (*w_, (struct sockaddr*) &addr, sizeof (addr)); - wsa_assert (rc != SOCKET_ERROR); - // Accept connection from writer. - *r_ = accept (listener, NULL, NULL); - wsa_assert (*r_ != INVALID_SOCKET); + // Save errno if connection fails + int conn_errno = 0; + if (rc == SOCKET_ERROR) { + conn_errno = WSAGetLastError (); + } else { + // Accept connection from writer. + *r_ = accept (listener, NULL, NULL); - // On Windows, preventing sockets to be inherited by child processes. - brc = SetHandleInformation ((HANDLE) *r_, HANDLE_FLAG_INHERIT, 0); - win_assert (brc); + if (*r_ == INVALID_SOCKET) { + conn_errno = WSAGetLastError (); + } + } // We don't need the listening socket anymore. Close it. rc = closesocket (listener); @@ -325,11 +329,33 @@ int zmq::signaler_t::make_fdpair (fd_t *r_, fd_t *w_) brc = SetEvent (sync); win_assert (brc != 0); - // Release the kernel object + // Release the kernel object brc = CloseHandle (sync); win_assert (brc != 0); - return 0; + if (*r_ != INVALID_SOCKET) { + // On Windows, preventing sockets to be inherited by child processes. + brc = SetHandleInformation ((HANDLE) *r_, HANDLE_FLAG_INHERIT, 0); + win_assert (brc); + + return 0; + } else { + // Cleanup writer if connection failed + rc = closesocket (*w_); + wsa_assert (rc != SOCKET_ERROR); + + *w_ = INVALID_SOCKET; + + // Set errno from saved value + errno = wsa_error_to_errno (conn_errno); + + // Ideally, we would return errno to the caller signaler_t() + // Unfortunately, it uses errno_assert() which gives "Unknown error" + // We might as well assert here and print the actual error message + wsa_assert_no (conn_errno); + + return -1; + } #elif defined ZMQ_HAVE_OPENVMS From d7cad1b52afc85550cdfc6dcd69fbbd25f0f6310 Mon Sep 17 00:00:00 2001 From: KIU Shueng Chuan Date: Sat, 29 Dec 2012 18:05:15 +0800 Subject: [PATCH 2/3] set SO_LINGER on first signaler socket to close in order to avoid TIME_WAIT state. --- src/signaler.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/signaler.cpp b/src/signaler.cpp index dd5c1fc6..19eafce1 100644 --- a/src/signaler.cpp +++ b/src/signaler.cpp @@ -95,7 +95,11 @@ zmq::signaler_t::~signaler_t () int rc = close (r); errno_assert (rc == 0); #elif defined ZMQ_HAVE_WINDOWS - int rc = closesocket (w); + struct linger so_linger = { 1, 0 }; + int rc = setsockopt (w, SOL_SOCKET, SO_LINGER, + (char *)&so_linger, sizeof (so_linger)); + wsa_assert (rc != SOCKET_ERROR); + rc = closesocket (w); wsa_assert (rc != SOCKET_ERROR); rc = closesocket (r); wsa_assert (rc != SOCKET_ERROR); From 26b182fe76d0f5ce21b541dc89f43be865ec73fa Mon Sep 17 00:00:00 2001 From: Pieter Hintjens Date: Sat, 18 May 2013 07:17:00 +0100 Subject: [PATCH 3/3] Backported #84 and #532 --- NEWS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NEWS b/NEWS index a01a7096..20cd9642 100644 --- a/NEWS +++ b/NEWS @@ -1,7 +1,9 @@ 0MQ version 3.2.4 stable, released on 2013/xx/xx ================================================ +* LIBZMQ-532 (Windows) critical section not released on error * LIBZMQ-456 ZMQ_XPUB_VERBOSE does not propagate in a tree of XPUB/XSUB devices +* LIBZMQ-84 (Windows) Assertion failed: Address already in use at signaler.cpp:80 0MQ version 3.2.3 stable, released on 2013/05/02