fixup! fixup! fixup! fixup! Rework Flare on Windows to use all Winsock2 methods with OVERLAPPED mode

This commit is contained in:
Tim Wojtulewicz 2024-02-08 18:48:00 -07:00
parent 303e83cb85
commit b2496ba6f9

View file

@ -45,6 +45,13 @@ Flare::Flare()
if ( sendfd == (int)INVALID_SOCKET ) if ( sendfd == (int)INVALID_SOCKET )
fatalError("WSASocket failure: %d", WSAGetLastError()); fatalError("WSASocket failure: %d", WSAGetLastError());
// Set both sockets in non-blocking mode.
u_long mode = 1;
if ( ioctlsocket((SOCKET)recvfd, FIONBIO, &mode) != 0 )
fatalError("Failed to set recv non-blocking mode: %d", WSAGetLastError());
if ( ioctlsocket((SOCKET)sendfd, FIONBIO, &mode) != 0 )
fatalError("Failed to set send non-blocking mode: %d", WSAGetLastError());
sockaddr_in sa; sockaddr_in sa;
memset(&sa, 0, sizeof(sa)); memset(&sa, 0, sizeof(sa));
sa.sin_family = AF_INET; sa.sin_family = AF_INET;
@ -157,10 +164,11 @@ int Flare::Extinguish(bool signal_safe) {
} }
#else #else
for ( ;; ) { for ( ;; ) {
// Get the number of bytes we can read without blocking, clamped to the size of our buffer. // Get the number of bytes we can read without blocking, clamped to the size of our
// buffer. If this returns zero, there's nothing to read and we can move on.
u_long bytes_to_read = 0; u_long bytes_to_read = 0;
if ( ioctlsocket((SOCKET)recvfd, FIONREAD, &bytes_to_read) != 0 ) if ( ioctlsocket((SOCKET)recvfd, FIONREAD, &bytes_to_read) != 0 )
fatalError("Failed to set non-blocking mode on recv socket: %d", WSAGetLastError()); fatalError("Failed to lookup available read buffer: %d", WSAGetLastError());
if ( bytes_to_read == 0 ) if ( bytes_to_read == 0 )
break; break;
if ( bytes_to_read > sizeof(tmp) ) if ( bytes_to_read > sizeof(tmp) )
@ -173,7 +181,9 @@ int Flare::Extinguish(bool signal_safe) {
continue; continue;
} }
if ( errno == EAGAIN || errno == EWOULDBLOCK ) // On Windows, recv may return -1 and set errno to NOERROR if there wasn't
// anything to read, instead of setting EAGAIN like UNIX does.
if ( errno == EAGAIN || errno == NOERROR)
// Success: pipe is now empty. // Success: pipe is now empty.
break; break;