From 81da391e7e6ee12a2607289a1aae16c400e7025e Mon Sep 17 00:00:00 2001 From: Martin Sustrik Date: Thu, 29 Sep 2011 14:47:41 +0200 Subject: Use single port for creating signalers on Windows Signed-off-by: Martin Sustrik --- src/signaler.cpp | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) (limited to 'src/signaler.cpp') diff --git a/src/signaler.cpp b/src/signaler.cpp index aac3e7c..e89f45a 100644 --- a/src/signaler.cpp +++ b/src/signaler.cpp @@ -59,6 +59,7 @@ #include "signaler.hpp" #include "likely.hpp" #include "stdint.hpp" +#include "config.hpp" #include "err.hpp" #include "fd.hpp" #include "ip.hpp" @@ -233,6 +234,17 @@ int zmq::signaler_t::make_fdpair (fd_t *r_, fd_t *w_) #elif defined ZMQ_HAVE_WINDOWS + // This function has to be in a system-wide critical section so that + // two instances of the library don't accidentally create signaler + // crossing the process boundary. + // We'll use named event object to implement the critical section. + HANDLE sync = CreateEvent (NULL, FALSE, FALSE, "zmq-signaler-port-sync"); + win_assert (sync != NULL); + + // Enter the critical section. + DWORD dwrc = WaitForSingleObject (sync, INFINITE); + zmq_assert (dwrc == WAIT_OBJECT_0); + // Windows has no 'socketpair' function. CreatePipe is no good as pipe // handles cannot be polled on. Here we create the socketpair by hand. *w_ = INVALID_SOCKET; @@ -258,15 +270,10 @@ int zmq::signaler_t::make_fdpair (fd_t *r_, fd_t *w_) memset (&addr, 0, sizeof (addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK); - addr.sin_port = 0; + addr.sin_port = htons (signaler_port); rc = bind (listener, (const struct sockaddr*) &addr, sizeof (addr)); wsa_assert (rc != SOCKET_ERROR); - // Retrieve local port listener is bound to (into addr). - int addrlen = sizeof (addr); - rc = getsockname (listener, (struct sockaddr*) &addr, &addrlen); - wsa_assert (rc != SOCKET_ERROR); - // Listen for incomming connections. rc = listen (listener, 1); wsa_assert (rc != SOCKET_ERROR); @@ -292,6 +299,10 @@ int zmq::signaler_t::make_fdpair (fd_t *r_, fd_t *w_) rc = closesocket (listener); wsa_assert (rc != SOCKET_ERROR); + // Exit the critical section. + BOOL brc = SetEvent (sync); + win_assert (brc != 0); + return 0; #elif defined ZMQ_HAVE_OPENVMS -- cgit v1.2.3