Bugfix in GSocket_Cleanup()

GSocket_Connect and GSocket_WaitConnection now detect EWOULDBLOCK
errors and act accordingly (this is needed for correct wxSocket
behaviour)


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@3587 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Guillermo Rodriguez Garcia
1999-09-08 22:13:48 +00:00
parent 2f85113366
commit aa3981f2c6

View File

@@ -99,7 +99,6 @@ bool GSocket_Init()
} }
firstAvailable = 0; firstAvailable = 0;
/* Initialize WinSocket */ /* Initialize WinSocket */
return (WSAStartup((1 << 8) | 1, &wsaData) == 0); return (WSAStartup((1 << 8) | 1, &wsaData) == 0);
} }
@@ -107,7 +106,7 @@ bool GSocket_Init()
void GSocket_Cleanup() void GSocket_Cleanup()
{ {
/* Destroy internal window */ /* Destroy internal window */
DestroyWindow(WINDOWNAME); DestroyWindow(hWin);
UnregisterClass(CLASSNAME, INSTANCE); UnregisterClass(CLASSNAME, INSTANCE);
/* Delete critical section */ /* Delete critical section */
@@ -409,15 +408,20 @@ GSocket *GSocket_WaitConnection(GSocket *sck)
} }
connection->m_fd = accept(sck->m_fd, NULL, NULL); connection->m_fd = accept(sck->m_fd, NULL, NULL);
ioctlsocket(connection->m_fd, FIONBIO, (u_long FAR *) &arg);
if (connection->m_fd == INVALID_SOCKET) if (connection->m_fd == INVALID_SOCKET)
{ {
if (WSAGetLastError() == WSAEWOULDBLOCK)
sck->m_error = GSOCK_WOULDBLOCK;
else
sck->m_error = GSOCK_IOERR;
GSocket_destroy(connection); GSocket_destroy(connection);
sck->m_error = GSOCK_IOERR;
return NULL; return NULL;
} }
ioctlsocket(connection->m_fd, FIONBIO, (u_long FAR *) &arg);
/* Initialize all fields */ /* Initialize all fields */
connection->m_server = FALSE; connection->m_server = FALSE;
connection->m_stream = TRUE; connection->m_stream = TRUE;
@@ -500,7 +504,7 @@ GSocketError GSocket_SetBroadcast(GSocket *sck)
GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream) GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream)
{ {
u_long arg = 1; u_long arg = 1;
int type, ret; int type, ret, err;
assert(sck != NULL); assert(sck != NULL);
@@ -536,19 +540,19 @@ GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream)
return GSOCK_IOERR; return GSOCK_IOERR;
} }
/* Connect it to the PEER address, with a timeout */ /* Connect it to the PEER address, with a timeout (see below) */
ret = connect(sck->m_fd, sck->m_peer->m_addr, sck->m_peer->m_len); ret = connect(sck->m_fd, sck->m_peer->m_addr, sck->m_peer->m_len);
if (ret == SOCKET_ERROR) if (ret == SOCKET_ERROR)
{ {
/* For blocking GSockets, if connect fails with an EWOULDBLOCK err = WSAGetLastError();
* error, then we can select() the socket for the specified
* timeout and check for writability to see if the connection /* If connect failed with EWOULDBLOCK and the GSocket object
* request completes. If the error is different than EWOULDBLOCK, * is in blocking mode, we select() for the specified timeout
* or if the socket is nonblocking, the call to GSocket_Connect() * checking for writability to see if the connection request
* has failed. * completes.
*/ */
if ((!sck->m_non_blocking) && (WSAGetLastError() == WSAEWOULDBLOCK)) if ((err == WSAEWOULDBLOCK) && (sck->m_non_blocking == FALSE))
{ {
if (_GSocket_Output_Timeout(sck) == GSOCK_TIMEDOUT) if (_GSocket_Output_Timeout(sck) == GSOCK_TIMEDOUT)
{ {
@@ -557,14 +561,29 @@ GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream)
/* sck->m_error is set in _GSocket_Input_Timeout */ /* sck->m_error is set in _GSocket_Input_Timeout */
return GSOCK_TIMEDOUT; return GSOCK_TIMEDOUT;
} }
else
return GSOCK_NOERROR;
} }
else /* error */
/* If connect failed with EWOULDBLOCK and the GSocket object
* is set to nonblocking, we set m_error to GSOCK_WOULDBLOCK
* (and return GSOCK_WOULDBLOCK) but we don't close the socket;
* this way if the connection completes, a GSOCK_CONNECTION
* event will be generated, if enabled.
*/
if ((err == WSAEWOULDBLOCK) && (sck->m_non_blocking == TRUE))
{ {
closesocket(sck->m_fd); sck->m_error = GSOCK_WOULDBLOCK;
sck->m_fd = INVALID_SOCKET; return GSOCK_WOULDBLOCK;
sck->m_error = GSOCK_IOERR;
return GSOCK_IOERR;
} }
/* If connect failed with an error other than EWOULDBLOCK,
* then the call to GSocket_Connect has failed.
*/
closesocket(sck->m_fd);
sck->m_fd = INVALID_SOCKET;
sck->m_error = GSOCK_IOERR;
return GSOCK_IOERR;
} }
return GSOCK_NOERROR; return GSOCK_NOERROR;
@@ -1202,7 +1221,7 @@ GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port,
port_int = atoi(port); port_int = atoi(port);
addr = (struct sockaddr_in *)address->m_addr; addr = (struct sockaddr_in *)address->m_addr;
addr->sin_port = htons(port_int); addr->sin_port = htons((u_short) port_int);
return GSOCK_NOERROR; return GSOCK_NOERROR;
} }