Tcl Source Code

View Ticket
Login
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: