@@ -292,7 +292,9 @@ const error_category& resolve_error_category()
292
292
static void throw_socket_error ()
293
293
{
294
294
#ifdef _WIN32
295
- throw_error (WSAGetLastError (), winsock_error_category ());
295
+ int error = WSAGetLastError ();
296
+ if (error)
297
+ throw_error (error, winsock_error_category ());
296
298
#else
297
299
throw_system_error ();
298
300
#endif
@@ -658,25 +660,41 @@ Socket connect(const char *host_name, unsigned short port,
658
660
if (connect_result == SOCKET_ERROR && errno == EINPROGRESS)
659
661
#endif
660
662
{
661
- auto timeout = duration_cast<microseconds>(
662
- deadline - system_clock::now ()
663
- ).count ();
664
663
665
- int select_result = poll_one (
666
- socket, POLL_MODE_CONNECT, true ,
667
- 0 == timeout_usec ? 0 : timeout > 0 ? timeout : 1
668
- );
664
+ int select_result = 0 ;
665
+
666
+ do {
667
+
668
+ auto timeout = duration_cast<microseconds>(
669
+ deadline - system_clock::now ()
670
+ ).count ();
671
+
672
+ select_result = poll_one (
673
+ socket, POLL_MODE_CONNECT, true ,
674
+ 0 == timeout_usec ? 0 : timeout > 0 ? timeout : 1
675
+ );
676
+ // Note: if poll_one() returns 0 then, according to POSIX specs:
677
+ // A value of 0 indicates that the call timed out and no file descriptors have been selected
678
+ // Due to a bug on WSApool, it may return 0 even if no timeout occur..
679
+ // So we will check if timeout occurs and try again if not
669
680
670
- if (select_result == 0 && (timeout_usec > 0 ) &&
671
- (std::chrono::system_clock::now () >= deadline))
681
+ } while ((select_result == 0 ) &&
682
+ ((timeout_usec == 0 ) ||
683
+ (std::chrono::system_clock::now () < deadline)
684
+ )
685
+ );
686
+
687
+ if ((timeout_usec > 0 ) &&
688
+ (std::chrono::system_clock::now () >= deadline))
672
689
{
673
690
// Throw the error in milliseconds, which we did not adjust.
674
691
// Otherwise the user will be confused why the timeout
675
692
// in the error message is smaller than defined
676
693
// (original timeout minus DNS resolution time)
677
694
throw Connect_timeout_error (timeout_usec / 1000 );
678
695
}
679
- else if (select_result < 0 )
696
+
697
+ if (select_result < 0 )
680
698
throw_socket_error ();
681
699
else
682
700
check_socket_error (socket);
@@ -858,8 +876,9 @@ DIAGNOSTIC_POP_CDK
858
876
#endif
859
877
860
878
if (fds.revents & (POLLERR | POLLHUP | POLLNVAL))
861
- check_socket_error (socket);
862
-
879
+ {
880
+ check_socket_error (socket);
881
+ }
863
882
864
883
return result;
865
884
}
0 commit comments