I guess I'm in more of the opposite camp. The example problem given tells me that they are "doing it wrong", but not for using a re-entrant mutex. If you have a class where "A::foo() acquires the lock. It then calls B::bar()" then you are already holding the lock too long. The mutex being non-reentrant isn't going to point this out to you. B::bar() might decide to do something that blocks or that tries to acquire some other lock and then you've got lock-acquisition order to worry about which leads to deadlock problems.

I've seen tons of code that uses re-entrant mutexes and isn't "doing it wrong". That example is more like: you have a class that mostly just deals with the bits that need to be under a specific mutex. So the code to be run under the mutex is kept very small and cohesive by being its own class that just concentrates on doing the locking right.

And the re-entrant mutex comes in because you have methods that mostly can tell that they don't need to grab the mutex and so don't most of the time. So, since you are only grabbing the mutex in the rare cases when you need it, you can easily end up with a simple and clear utility method that might be called in a context where the mutex isn't held and also in contexts where the mutex is held and the utility function might (even indirectly) only rarely decide that it needs to hold the mutex.

You can get around that by splitting any such method into two methods, say doFooUnlocked() that just does the work and doFooLocked() that just holds the mutex and then calls doFooUnlocked(). Then doFooUnlocked() might be declared such that it can only be called from within the class. Then, if you already are holding the mutex, you need to call doFooUnlocked().

But, that solution requires the bifurcation of all methods that might call doFoo*() which can lead to quite a mess.

But this type of concern mostly only pops up when doing the style of threading + locking that Java pretty much encourages and I find that that is an approach that is just way too easy to end up becoming an unreliable mess after it tries to scale in the feature set supported. So I don't do anything like that these days.

I wish I had a much more concrete example handy but it has been too many years since I was doing that type of work (in C++).

- tye        


In reply to Re: Recursive locks:killer application. Do they have one? (mu) by tye
in thread Recursive locks:killer application. Do they have one? by BrowserUk

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.