buglwIP - A Lightweight TCP/IP stack - Bugs: bug #32784, Race condition when sending to UDP...

 
 

You are not allowed to post comments on this tracker with your current authentication level.

bug #32784: Race condition when sending to UDP socket from multiple threads

Submitter:  Ken MacKay <kmackay>
Submitted:  Mon 14 Mar 2011 09:10:57 PM UTC
   
 
Category:  UDP Severity:  3 - Normal
Item Group:  Faulty Behaviour Status:  Wont Fix
Privacy:  Public Assigned to:  goldsimon
Open/Closed:  Closed Planned Release:  None
lwIP version:  CVS Head

Mon 14 Mar 2011 09:24:00 PM UTC, comment #1: 

Sorry to turn you down on this, but sharing a socket between multiple threads is not supported in lwIP. It's just a limitation imposed by the 'lw' in lwIP. Doesn't depend on the protocol, it doesn't work for RAW and TCP, too: when I started with lwIP, I expected this to work for TCP to be able to read from one thread while writing from another to implement a full-duplex protocol.

You can work around this by using a semaphore (as you stated), but it's not planned to be integrated into our CVS code, currently.

Simon Goldschmidt <goldsimon>
Group administrator
Mon 14 Mar 2011 09:10:57 PM UTC, original submission:  

When multiple threads are sending over the same UDP socket (using sendto()), there is a race condition in tcpip_apimsg(). What happens is that one thread (thread 1) enters tcpip_apimsg() and posts to the tcpip thread. The tcpip thread then runs the do_send function and signals the conn->op_completed semaphore. Then the tcpip thread goes back to blocking on the mbox.

At this point, if a different thread (thread 2) is selected to run, the conn->op_completed semaphore is already set. That means that when thread 2 calls sendto() and enters tcpip_apimsg(), it posts the operation to the mbox and then waits on the semaphore. Since the semaphore is already signalled, it returns immediately. Then, when the tcpip thread runs the operation, it corrupts the stack of thread 2.

I fixed this issue by adding a semaphore to struct lwip_sock, and locking it while calling netconn_send() in lwip_sendto(). I'm not sure if this is the best way to do it though.

I'm not sure what the correct behaviour is here. Sending to a UDP socket from multiple threads works on other platforms. However, it is not difficult for the application to manage the locking properly. The locked region would be larger than if the locking were done in lwIP itself.

It seems like sending to / receiving from a UDP socket from multiple threads should work since UDP sends datagrams; I wouldn't expect it to work with TCP since the stream would get garbled. Note that I didn't try receiving from multiple threads, but I assume it works in a similar way.

Ken MacKay <kmackay>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by goldsimon (Posted a comment)
  • -email is unavailable- added by kmackay (Submitted the item)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

     

    Follow 3 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2011-03-14 goldsimon StatusNone Wont Fix
        Assigned toNone goldsimon
        Open/ClosedOpen Closed

    Back to the top

    Powered by Savane 3.13-bb6a.
    Corresponding source code