|
Boost : |
From: Preston A. Elder (prez_at_[hidden])
Date: 2007-10-23 19:01:09
Hi,
I have written a refinement on boost::mutex that allows for it to be
interrupted while waiting to acquire the mutex by altering a predicate
(once the mutex is acquired, it acts like a regular mutex).
Here is the code:
http://www.neuromancy.net/fisheye/browse/mantra/trunk/Mantra-I/mantra/utils/interruptable_mutex.h?r=419
It has been fully unit tested. The idea is simple, using an
interruptable_mutex operates exactly like a boost::mutex normally, so
boost::interruptable_mutex mtx;
{
boost::interruptable_mutex::scoped_lock sl(mtx);
...
}
All fine.
However, if you want the ability to be able to interrupt the mutex while
blocked waiting to acquire, you could do:
boost::interruptable_mutex mtx;
boost::interruptable_pred pred(mtx);
{
boost::interruptable_pred::scoped_lock sl(pred);
...
}
Then in another thread, I could call:
pred(true);
and it will throw an exception in the thread waiting to acquire the
scoped_lock. This works when waiting on reacquisition of a lock after
a condition just as well, eg:
{
boost::interruptable_pred::scoped_lock sl(pred);
...
boost::condition cond;
cond.wait(sl);
// Assuming we got signaled, we would reacquire sl, however if
// multiple threads were trying to acquire sl, we could block
// waiting for the lock re-acquisition, that is breakable.
}
In addition to this, the implementation I have allows you to register
a callback function that will be invoked in place of just throwing an
exception.
The reason the interruptable_pred is a separate class is that you may
want multiple predicates associated with the same lock. For example
a situation where the lock is for a queue, and you are pushing multiple
messages to that queue. Each message would have a interruptable_pred
created for it, but constructed with the same interruptable_mutex, the
one guarding the queue. This way you can interrupt the lock acquire
for a single message only without interrupting others also waiting.
As with all my submissions, do with it as you please. I have unit
tested it, and it works here. I just don't believe this should be
submitted as a separate component, but more folded into boost::thread.
PreZ :)
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk