Here is an initial patch to add some thread protection to the client c++ library.
Basically this adds a mutex to the clientproxy class which is accessed with Lock()
and Unlock() calls. The Read function will call lock/unlock around any updates to a
clientproxy, so to ensure thread safety simply call Lock in the client application
when you are accessing data...
The patch was much simpler than I first expected.
The application must still make sure that there are not two threads expecting to
read datat from the server at the same time (ie constructing a client proxy which
expects an access message to have a response and a playerclient read as one thread
will steal the data from the other causing deadlock.
Brian Gerkey wrote:
>On Mon, 5 Jul 2004, Toby Collett wrote:
>>There are two basic issues...
>>1) the read call is blocking and does the data updates, so in order to
>>be thread safe I have to hold a mutex lock on a blocking call (not good
>>2) Additional proxies may be added to the playerclient object after the
>>update thread is started (ie blocking on the read)
>>if i am in pull new mode and no new data is coming in then the blocking
>>read blocks for ever...this also blocks the server thread for the client
>>connection and thus the request device access calls also block (so no
>>new devices can connect to break the read lock)
>>The first issue can probably solved by simply creating two calls, "Read"
>>and "PushDataToProxies" (probably not good names) that way you can
>>simply lock in the second call...
>That sounds like a good idea.
>>The second issue is a little more complex I guess...would it be easy to
>>allow the server to react to new commands while it is waiting on data
>>from the drivers? I guess its only fatal when you do a pull new read on
>>a playerclient with no active proxies.....so could simply fail a
>>playerclient read when no proxies are active for the client...
>I'm not sure exactly what's going on here. The client should be getting
>SYNC messages every cycle, regardless of whether there's any data or
>any subscribed devices. Receipt of a SYNC message should cause Read()
>Can you more clearly describe what's going on when Read() hangs
>>Finally, should any 'thread safing' be done as a few function changes
>>that allow client software to force thread safety (ie by manually
>>calling 'read new data' 'then client side lock' then 'push updates to
>>proxies' then 'unlock', or as a compile flag in the client so thread
>>safety is transparent (--enable-threadsafe-clientlibs)
>I would do the following: Add a pthread_mutex_t to PlayerClient, and
>provide public Lock() and Unlock() methods. Have PushDataToProxies()
>always call Lock() and Unlock() appropriately (neglible overhead).
>Then leave it up to the user to call Lock() and Unlock() when accessing
>the client object if thread safety is needed.
>>Let me know if im plain old going about this the wrong way, or which of
>>the above options will work/wont work....
>Sounds great; just send a patch!
University of Auckland Robotics Group