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/config.hpp | 6 +++++- src/signaler.cpp | 23 +++++++++++++++++------ 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 -- cgit v1.2.3