BUG: Race Between 2 Threads Sharing a Socket Causes Problem

Last reviewed: September 29, 1995
Article ID: Q126346
The information in this article applies to:
  • Microsoft Win32 Device Development Kit (DDK) for Windows NT version 3.5

SYMPTOMS

Packets between the TCP, UDP, and IP layers are lost.

CAUSE

There appears to be a problem with a race condition between two threads that share a socket where one is closing a socket while the other tries to call recvfrom() on the same socket. This causes problems the next time a socket is bound to the same UDP port.

RESOLUTION

The vendor should implement a workaround within the application so that this race condition does not occur.

STATUS

Microsoft has confirmed this to be a problem in the Microsoft products listed at the beginning of this article. We are researching this problem and will post new information here in the Microsoft Knowledge Base as it becomes available.

MORE INFORMATION

This Sockets/UDP problem was discovered while testing the TX1000 NCPI driver for Windows NT. Here are some notes showing what appears to be happening:

Thread 1                        Thread 2
--------                        ---------
Create DGRAM socket x Bind socket x to:
        IPADDR = ANY
        PORT = 1571
Create thread 2 ----------------->
                                RecvFrom on socket x
                                ...
                                Packet received on x (recvfrom completes)
                <---------------signal main thread
Process rec'd packet            wait for main thread to consume buffer
Signal buffer available--------->
                                RecvFrom on socket x
                                ...  { repeats many times }

Normal Shutdown Sequence (on Last Packet)

                                Packet received on x (recvfrom completes)
                <---------------signal main thread
Process rec'd packet            wait for main thread to consume buffer
Signal buffer available--------->
Application done                (1) RecvFrom on socket x
(2) close socket x
                                (3) RecvFrom fails with expected error
                                Thread terminates

Usually, events occur in sequence (1, 2, then 3). In this normal case, the socket is cleared correctly, and everything works the next time the application runs.

Shutdown Sequence that Causes Problems (on Last Packet)

                                Packet received on x (recvfrom completes)
                <---------------signal main thread
Process rec'd packet            wait for main thread to consume buffer
Signal buffer available---------> Application done
(1) close socket x              (2) RecvFrom on socket x
                                (3) RecvFrom fails with expected error
                                Thread terminates

In this case, the sequence is slightly different. The closesocket() function from main thread starts, but does not complete, before thread 2 runs. While thread 1 is suspended awaiting completion of closesocket(), thread 2 runs and posts next recvfrom() on same socket. The closesocket() function completes successfully, and recvfrom() fails as in normal case. But the next time the application runs and binds to the same UDP port, the following occurs:
  • All socket calls (bind(), recvfrom()) are successful
  • All incoming packets to that UDP port are discarded before reaching the application -- recvfrom() never completes. The following command shows that the "receive errors" count has been incremented once for each incoming packet that was lost:

    netstat -s -p udp

The conclusion is that in this case the socket was not cleaned up properly due to the race condition between the closesocket() and the recvfrom() functions.


Additional reference words: 3.50
KBCategory: kbnetwork
KBSubcategory: NtwkWinsock


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: September 29, 1995
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.