summaryrefslogtreecommitdiffstats
path: root/win
diff options
context:
space:
mode:
authoroehhar <harald.oehlmann@elmicron.de>2014-04-02 12:43:29 (GMT)
committeroehhar <harald.oehlmann@elmicron.de>2014-04-02 12:43:29 (GMT)
commit7d3ace5344fa211a19628c2ddec28510b515fa4c (patch)
tree23996255a826e971b126afeef032fdf50009a66b /win
parent30a15d58d30ef07b7bcf90e876e495fdfb55a830 (diff)
parent6db3b6dd9d1acdae281ff36db51632a2efbf1853 (diff)
downloadtcl-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.c73
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;
/*