2323#include " tcp.hpp"
2424#ifdef ZMQ_HAVE_IPC
2525#include " ipc_address.hpp"
26+ // Don't try ipc if it fails once
27+ namespace zmq
28+ {
29+ static bool try_ipc_first = true ;
30+ }
2631#endif
2732
2833#include < direct.h>
@@ -555,9 +560,14 @@ int zmq::make_fdpair (fd_t *r_, fd_t *w_)
555560
556561 // It appears that a lack of runtime AF_UNIX support
557562 // can fail in more than one way.
558- // At least: open_socket can fail or later in bind
563+ // At least: open_socket can fail or later in bind or even in connect after bind
559564 bool ipc_fallback_on_tcpip = true ;
560565
566+ if (!zmq::try_ipc_first) {
567+ // a past ipc attempt failed, skip straight to try_tcpip in the future;
568+ goto try_tcpip;
569+ }
570+
561571 // Create a listening socket.
562572 const SOCKET listener = open_socket (AF_UNIX, SOCK_STREAM, 0 );
563573 if (listener == retired_fd) {
@@ -585,8 +595,7 @@ int zmq::make_fdpair (fd_t *r_, fd_t *w_)
585595 goto error_closelistener;
586596 }
587597 // if we got here, ipc should be working,
588- // so raise any remaining errors
589- ipc_fallback_on_tcpip = false ;
598+ // but there are at least some cases where connect can still fail
590599
591600 // Listen for incoming connections.
592601 rc = listen (listener, 1 );
@@ -597,24 +606,28 @@ int zmq::make_fdpair (fd_t *r_, fd_t *w_)
597606
598607 rc = getsockname (listener, reinterpret_cast <struct sockaddr *> (&lcladdr),
599608 &lcladdr_len);
600- wsa_assert (rc != - 1 );
609+ wsa_assert (rc == 0 );
601610
602611 // Create the client socket.
603612 *w_ = open_socket (AF_UNIX, SOCK_STREAM, 0 );
604- if (*w_ == - 1 ) {
613+ if (*w_ == retired_fd ) {
605614 errno = wsa_error_to_errno (WSAGetLastError ());
606615 goto error_closelistener;
607616 }
608617
609618 // Connect to the remote peer.
610619 rc = ::connect (*w_, reinterpret_cast <const struct sockaddr *> (&lcladdr),
611620 lcladdr_len);
612- if (rc == -1 ) {
621+ if (rc != 0 ) {
622+ errno = wsa_error_to_errno (WSAGetLastError ());
613623 goto error_closeclient;
614624 }
625+ // if we got here, ipc should be working,
626+ // so raise any remaining errors
627+ ipc_fallback_on_tcpip = false ;
615628
616629 *r_ = accept (listener, NULL , NULL );
617- errno_assert (*r_ != - 1 );
630+ wsa_assert (*r_ != retired_fd );
618631
619632 // Close the listener socket, we don't need it anymore.
620633 rc = closesocket (listener);
@@ -636,6 +649,7 @@ int zmq::make_fdpair (fd_t *r_, fd_t *w_)
636649 saved_errno = errno;
637650 rc = closesocket (*w_);
638651 wsa_assert (rc == 0 );
652+ *w_ = retired_fd;
639653 errno = saved_errno;
640654
641655error_closelistener:
@@ -663,9 +677,13 @@ int zmq::make_fdpair (fd_t *r_, fd_t *w_)
663677
664678try_tcpip:
665679 // try to fallback to TCP/IP
666- // TODO: maybe remember this decision permanently?
667- #endif
668-
680+ rc = make_fdpair_tcpip (r_, w_);
681+ if (rc == 0 && zmq::try_ipc_first) {
682+ // ipc didn't work but tcp/ip did; skip ipc in the future
683+ zmq::try_ipc_first = false ;
684+ }
685+ return rc;
686+ #endif // ZMQ_HAVE_IPC
669687 return make_fdpair_tcpip (r_, w_);
670688#elif defined ZMQ_HAVE_OPENVMS
671689
0 commit comments