23
23
#include " tcp.hpp"
24
24
#ifdef ZMQ_HAVE_IPC
25
25
#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
+ }
26
31
#endif
27
32
28
33
#include < direct.h>
@@ -555,9 +560,14 @@ int zmq::make_fdpair (fd_t *r_, fd_t *w_)
555
560
556
561
// It appears that a lack of runtime AF_UNIX support
557
562
// 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
559
564
bool ipc_fallback_on_tcpip = true ;
560
565
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
+
561
571
// Create a listening socket.
562
572
const SOCKET listener = open_socket (AF_UNIX, SOCK_STREAM, 0 );
563
573
if (listener == retired_fd) {
@@ -585,8 +595,7 @@ int zmq::make_fdpair (fd_t *r_, fd_t *w_)
585
595
goto error_closelistener;
586
596
}
587
597
// 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
590
599
591
600
// Listen for incoming connections.
592
601
rc = listen (listener, 1 );
@@ -597,24 +606,28 @@ int zmq::make_fdpair (fd_t *r_, fd_t *w_)
597
606
598
607
rc = getsockname (listener, reinterpret_cast <struct sockaddr *> (&lcladdr),
599
608
&lcladdr_len);
600
- wsa_assert (rc != - 1 );
609
+ wsa_assert (rc == 0 );
601
610
602
611
// Create the client socket.
603
612
*w_ = open_socket (AF_UNIX, SOCK_STREAM, 0 );
604
- if (*w_ == - 1 ) {
613
+ if (*w_ == retired_fd ) {
605
614
errno = wsa_error_to_errno (WSAGetLastError ());
606
615
goto error_closelistener;
607
616
}
608
617
609
618
// Connect to the remote peer.
610
619
rc = ::connect (*w_, reinterpret_cast <const struct sockaddr *> (&lcladdr),
611
620
lcladdr_len);
612
- if (rc == -1 ) {
621
+ if (rc != 0 ) {
622
+ errno = wsa_error_to_errno (WSAGetLastError ());
613
623
goto error_closeclient;
614
624
}
625
+ // if we got here, ipc should be working,
626
+ // so raise any remaining errors
627
+ ipc_fallback_on_tcpip = false ;
615
628
616
629
*r_ = accept (listener, NULL , NULL );
617
- errno_assert (*r_ != - 1 );
630
+ wsa_assert (*r_ != retired_fd );
618
631
619
632
// Close the listener socket, we don't need it anymore.
620
633
rc = closesocket (listener);
@@ -636,6 +649,7 @@ int zmq::make_fdpair (fd_t *r_, fd_t *w_)
636
649
saved_errno = errno;
637
650
rc = closesocket (*w_);
638
651
wsa_assert (rc == 0 );
652
+ *w_ = retired_fd;
639
653
errno = saved_errno;
640
654
641
655
error_closelistener:
@@ -663,9 +677,13 @@ int zmq::make_fdpair (fd_t *r_, fd_t *w_)
663
677
664
678
try_tcpip:
665
679
// 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
669
687
return make_fdpair_tcpip (r_, w_);
670
688
#elif defined ZMQ_HAVE_OPENVMS
671
689
0 commit comments