Avoiding deadlock with mutex trylock in multithreaded app.

Pierre Mallard mallard.pierre@gmail.com
Sat Aug 8 14:24:00 GMT 2009


Hi,

Sorry for this long mail, and thanks for your help and advice :

I have a question regarding proper handling of non concurrent access
between two (or more) thread that deals together on a
register/unregister + callback way.

Let's try to be clear !

A Threaded Module "A" acts like this :
It offers two function to a module B and has a main task :
 "A_register" register request, called by module B in a Start
function, called by a thread "C"
 "A_unregister" unregister request , called by module B in a Release
function, in a thread "C"
 "A_process" a thread main task that loop forever and unqueue request,
call multiple time the callback that comes with the request untill
request processing is finished and start again

A module B that is driven by a task C that has three function :
"B_start" register to A
"B_callback" calls by A during request processing
"B_release" unregister to A, and destroy B

I need to avoid B_callback to be called during and after B_release

I can think of two way things could work :
   A "deadlock way" that leads to a deadlock (!),
   A "Trylock way" that requires trylock

I present here both approach and attached a code sample to illustrate
the trylock way I can think of.

I am wondering whether the trylock approach is the good one, and also
how could I avoid the waste of time (and CPU !) trying to lock mutex_B
?

************************************************************
"The deadlock way"
A Module A mutex between callback calls and unregister function, to
check if request is still existing,
A Module B mutex between release and callback.
But that leads to a dead lock :

=====================================
Thread A
=====================================
"A_process" lock mutex_A to check whether request is still registered
if !stop_cur_request
  B_Callback lock/unlock mutex_B
unlock mutex_A

=====================================
Thread C
=====================================
"B_release" lock mutex_B
  "A_Unregister" lock/unlock mutex A
unlock mutex_B

The dead lock appears because in task A we lock mutex_A then mutex_B
and in task C we lock mutex_B then mutex_A.

***********************************************************
"The TryLock way"
I can Trylock instead of lock in Callback, Therefore, when release is
called and lock mutex_B, callback won't hold mutex_A if it realize
mutex_B is busy.

=====================================
Thread A
=====================================
"A_process"
...
while (TRUE)
      lock mutex_A
      if !stop_cur_request
      	 if Call Callback == RETRY <-- TryLock Failed
	    unlock mutex_A
      	 else
	    break
	 endif
      endif
endWhile
unlock mutex_A
...


Thanks a lot for your attention, comments and advice,
Regards,
Pierre


-- 
Pierre Mallard
-------------- next part --------------
A non-text attachment was scrubbed...
Name: trylock.c
Type: text/x-csrc
Size: 3610 bytes
Desc: not available
URL: <http://sourceware.org/pipermail/libc-help/attachments/20090808/5c5a6bb2/attachment.bin>


More information about the Libc-help mailing list