Okay, so I’m having another look at the alternative threading ideas
which are part of my threading article. (They’re not that big an
alternative really – not compared with CSP etc – they’d just make
things more pleasant.) I want to add deadlock prevention to my locks,
making it impossible to lock things incorrectly (so long as you’re
locking the simple way – if you lock the associated monitor
independently, that’s your own lookout). Obviously this requires you to
set up what’s correct and what’s incorrect to start with. My question
to you all is: how do you want to be able to set up those
rules? What kind of rules do you need? Do they need to be extensible
somehow? Some desirable things may be impossible, but I’d like to know
what the ideal would look like before working out the realistic. I have
a couple of pretty simple ideas, but I won’t taint your own views by
mentioning them yet…
I use very simple rules:
* Must always lock in the same order
* Must always release in reverse order of locking
And I verify it with something like this:
http://www.ayende.com/Blog/2005/12/19/MockingChallangeMockingTDDAndMultiThreading.aspx
LikeLike
I agree with Ayende. You can think up crazy schemes that would check for cyclic lock acquisition, use lock timeouts, etc. Then you’re into a database world and System.Transactions, which is probably the wrong side of the things. I would start off simple with in-order lock acquisition (and reverse release) – throw an exception on out-of-order acquisition. Maybe make the strategy extensible/pluggable when you create your lock manager and see how people use it.
LikeLike
Good. That’s about what I was after.
Now, in terms of ordering – I believe (after thinking about it for a while) that you just need to provide an order (eg A -> B -> C) and it should ensure that you never take out A when you already own B *or* C (unless you already own A as well). You can, however, take out C without owning anything else – otherwise there’d be no point in having more than one lock in the first place.
Sound about right?
Oh, and is a single chain enough, or should I be able to express:
A->B->C
A->D->E
(i.e. A has two “nested” locks)?
I can’t immediately see the use of this, which makes me suggest I shouldn’t bother – just keep the single chain. Reasonable?
Likewise, I don’t think I’ll bother (at first) checking for out-of-order release. The easiest way of using the locks I’m creating is with the “using” statement, which will ensure you get things right anyway in that respect. You need to have access to the underlying monitor for other reasons anyway, and I’m taking (at the moment) an attitude of “if you really want to screw things up, you still can – but you’re unlikely to do it by accident”. Also known as “the easy way is the right way” :)
Please shout me down if it sounds like I’m going the wrong way. (Not that this is actually written at all yet.)
LikeLike