Ticket UUID: | 410674 | |||
Title: | Bug fix: #219205 and 219333 (event drop) | |||
Type: | Patch | Version: | None | |
Submitter: | ashmael | Created on: | 2001-03-23 01:44:48 | |
Subsystem: | 27. Channel Types | Assigned To: | hobbs | |
Priority: | 5 Medium | Severity: | ||
Status: | Closed | Last Modified: | 2002-12-19 03:38:04 | |
Resolution: | Fixed | Closed By: | hobbs | |
Closed on: | 2002-12-18 20:38:04 | |||
Description: |
This is a patch I believe to to fix bugs #219205 and #219333 regarding dropped socket events on Windows. The fix consists of moving the SendMessage() call that re-enables the WSAAsyncSelect() handler to outside the else {} block so that it will be called regardless of the select() return value. See Bug #219205 for a more detailed analysis of the bug fix. | |||
User Comments: |
hobbs added on 2002-12-19 03:38:04:
Logged In: YES user_id=72656 8.3.2 would be prior to the mentioned bug fix. If you still have the issue in 8.4.1 (or perhaps it was backported for 8.3.5), then please submit a new bug report with your patch. kensdorf added on 2002-12-19 02:14:23: Logged In: YES user_id=671771 We have seen a similar problem in version 8.3.2. We determined that it has to do with the FD_ACCEPT bit being cleared prematurely when two "accept" events come in simultaneously. This happens due to a race condition in the code where the infoPtr's acceptEventCount is checked and the flag is subsequntly cleared. If an accept event occurs during this operation, it will never be processed if the FD_ACCEPT flag is cleared by the tcl application thread after it has been set by the "SocketProc" thread. We fixed this by protecting access to this flag and the acceptEventCount variable with a critical section object. If anyone would like more details about our fix, please let me know. hobbs added on 2001-03-31 07:39:06: Logged In: YES user_id=72656 After some back and forth discussion, it was decided to go with: diff -b -c -r1.19 tclWinSock.c *** win/tclWinSock.c 2000/09/28 06:38:23 1.19 --- win/tclWinSock.c 2001/03/31 00:27:25 *************** *** 836,844 **** if ((*winSock.select)(0, &readFds, NULL, NULL, &timeout) != 0) { mask |= TCL_READABLE; } else { SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM) SELECT, (LPARAM) infoPtr); - infoPtr->readyEvents &= ~(FD_READ); } } if (events & (FD_WRITE | FD_CONNECT)) { --- 836,844 ---- if ((*winSock.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)) { This just moves the infoPtr flag correction before the SendMessage. It appears we were hitting a rare race condition that could cause the hang, where the recipient of the SendMessage received the message before the infoPtr flags could be corrected. This was tested again from 8.2- 8.4a2. In 8.4a2cvs. hobbs added on 2001-03-24 10:00:12: Logged In: YES user_id=72656 The patch is off by a few lines for 8.4a2, but it does pass all the test suites after being applied. Also an example with C source now passes that still failed in pre-patch 8.4a2 code. ashmael added on 2001-03-23 08:44:51: File Added - 4543: tclWinSock.c.patch |
Attachments:
- tclWinSock.c.patch [download] added by ashmael on 2001-03-23 08:44:50. [details]