diff options
author | oehhar <harald.oehlmann@elmicron.de> | 2014-04-02 12:43:29 (GMT) |
---|---|---|
committer | oehhar <harald.oehlmann@elmicron.de> | 2014-04-02 12:43:29 (GMT) |
commit | 7d3ace5344fa211a19628c2ddec28510b515fa4c (patch) | |
tree | 23996255a826e971b126afeef032fdf50009a66b /win | |
parent | 30a15d58d30ef07b7bcf90e876e495fdfb55a830 (diff) | |
parent | 6db3b6dd9d1acdae281ff36db51632a2efbf1853 (diff) | |
download | tcl-7d3ace5344fa211a19628c2ddec28510b515fa4c.zip tcl-7d3ace5344fa211a19628c2ddec28510b515fa4c.tar.gz tcl-7d3ace5344fa211a19628c2ddec28510b515fa4c.tar.bz2 |
Fix bug [581937ab1e]: fire readable event on async socket connect failurebug_581937ab1e
Diffstat (limited to 'win')
-rw-r--r-- | win/tclWinSock.c | 73 |
1 files changed, 40 insertions, 33 deletions
diff --git a/win/tclWinSock.c b/win/tclWinSock.c index e7b086a..aa298f5 100644 --- a/win/tclWinSock.c +++ b/win/tclWinSock.c @@ -719,44 +719,52 @@ SocketEventProc( Tcl_SetMaxBlockTime(&blockTime); mask |= TCL_READABLE|TCL_WRITABLE; } else if (events & FD_READ) { - fd_set readFds; - struct timeval timeout; - /* - * We must check to see if data is really available, since someone - * could have consumed the data in the meantime. Turn off async - * notification so select will work correctly. If the socket is still - * readable, notify the channel driver, otherwise reset the async - * select handler and keep waiting. + * Throw the readable event if an async connect failed. */ - SendMessage(tsdPtr->hwnd, SOCKET_SELECT, - (WPARAM) UNSELECT, (LPARAM) infoPtr); - - FD_ZERO(&readFds); - FD_SET(infoPtr->socket, &readFds); - timeout.tv_usec = 0; - timeout.tv_sec = 0; + if (infoPtr->lastError) { - if (select(0, &readFds, NULL, NULL, &timeout) != 0) { mask |= TCL_READABLE; + } else { - infoPtr->readyEvents &= ~(FD_READ); - SendMessage(tsdPtr->hwnd, SOCKET_SELECT, - (WPARAM) SELECT, (LPARAM) infoPtr); - } - } - if (events & (FD_WRITE | FD_CONNECT)) { - mask |= TCL_WRITABLE; - if (events & FD_CONNECT && infoPtr->lastError != NO_ERROR) { + fd_set readFds; + struct timeval timeout; + /* - * Connect errors should also fire the readable handler. + * We must check to see if data is really available, since someone + * could have consumed the data in the meantime. Turn off async + * notification so select will work correctly. If the socket is still + * readable, notify the channel driver, otherwise reset the async + * select handler and keep waiting. */ - mask |= TCL_READABLE; + SendMessage(tsdPtr->hwnd, SOCKET_SELECT, + (WPARAM) UNSELECT, (LPARAM) infoPtr); + + FD_ZERO(&readFds); + FD_SET(infoPtr->socket, &readFds); + timeout.tv_usec = 0; + timeout.tv_sec = 0; + + if (select(0, &readFds, NULL, NULL, &timeout) != 0) { + mask |= TCL_READABLE; + } else { + infoPtr->readyEvents &= ~(FD_READ); + SendMessage(tsdPtr->hwnd, SOCKET_SELECT, + (WPARAM) SELECT, (LPARAM) infoPtr); + } } } + /* + * writable event + */ + + if (events & FD_WRITE) { + mask |= TCL_WRITABLE; + } + if (mask) { Tcl_NotifyChannel(infoPtr->channel, mask); } @@ -2409,19 +2417,18 @@ SocketProc( */ if (error != ERROR_SUCCESS) { + /* Async Connect error */ TclWinConvertWSAError((DWORD) error); infoPtr->lastError = Tcl_GetErrno(); + /* Fire also readable event on connect failure */ + infoPtr->readyEvents |= FD_READ; } - } - if (infoPtr->flags & SOCKET_ASYNC_CONNECT) { - infoPtr->flags &= ~(SOCKET_ASYNC_CONNECT); - if (error != ERROR_SUCCESS) { - TclWinConvertWSAError((DWORD) error); - infoPtr->lastError = Tcl_GetErrno(); - } + /* fire writable event on connect */ infoPtr->readyEvents |= FD_WRITE; + } + infoPtr->readyEvents |= event; /* |