summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/config.hpp6
-rw-r--r--src/signaler.cpp23
2 files changed, 22 insertions, 7 deletions
diff --git a/src/config.hpp b/src/config.hpp
index 96e39de..8e512bb 100644
--- a/src/config.hpp
+++ b/src/config.hpp
@@ -79,7 +79,11 @@ namespace zmq
clock_precision = 1000000,
// Maximum transport data unit size for PGM (TPDU).
- pgm_max_tpdu = 1500
+ pgm_max_tpdu = 1500,
+
+ // On some OSes the signaler has to be emulated using a TCP
+ // connection. In such cases following port is used.
+ signaler_port = 5905
};
}
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