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

Submitted by:  Ken MacKay <kmackay>
Submitted on:  Mon 14 Mar 2011 09:10:57 PM UTC  
 
Category: UDPSeverity: 3 - Normal
Item Group: Faulty BehaviourStatus: Wont Fix
Privacy: PublicAssigned to: Simon Goldschmidt <goldsimon>
Open/Closed: ClosedPlanned 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>
Project AdministratorIn charge of this item.
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>

 

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

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

    Do you think this task is very important?
    If so, you can click here to add your encouragement to it.
    This task has 0 encouragements so far.

    Only logged-in users can vote.

     

    Please enter the title of George Orwell's famous dystopian book (it's a date):

     

     

    Follow 3 latest changes.

    Date Changed By Updated Field Previous Value => Replaced By
    Mon 14 Mar 2011 09:24:00 PM UTCgoldsimonStatusNone=>Wont Fix
      Assigned toNone=>goldsimon
      Open/ClosedOpen=>Closed

    Back to the top


    Powered by Savane 3.1-cleanup1