|
Boost : |
From: William Kempf (sirwillard_at_[hidden])
Date: 2000-08-18 16:54:55
--- In boost_at_[hidden], "Greg Colvin" <gcolvin_at_u...> wrote:
> From: "William Kempf" <sirwillard_at_m...>
> > --- In boost_at_[hidden], "Greg Colvin" <gcolvin_at_u...> wrote:
> > > From: "William Kempf" <sirwillard_at_m...>
> > > > ...
> > > > The problem with the CV is that we've only insured that the
> > > > associated mutex is locked in the call to wait() but not in
the call
> > > > to notify(). It would be nice if we could have some manner
in which
> > > > we can insure that we've locked the mutex at compile time for
both of
> > > > these, though I think we'll likely have to settle for an
exception at
> > > > run time. If you've seen Jeremy's documentation maybe you
have some
> > > > thoughts on this?
> > >
> > > Earlier I suggested that the lock, wait condition, and notify
could be
> > > combined into a single object with a templated constructor.
> >
> > This doesn't address the problem. Just combining them into a
single
> > object won't solve the problem of needing the mutex to be locked
> > during calls to wait() and notify().
> >
> > Besides, the lock can't be combined in this way ...
>
> Maybe I'm missing something, but I don't see why something like
> following wouldn't work:
>
> struct mutex {
> struct condition {
> condition(mutex*);
> bool wait(int);
> void notify();
> };
> struct timeout_exception : exception {};
> struct wait {
> wait(mutex*, lambda_functor predicate,
> condition in,condition out,int timeout=-1)
> : mtx(mtx), in(in), out(out) {
> mtx->enter();
> do {
> if (in.wait(timeout))
> throw(timeout_exception());
> } while(!predicate());
> }
> ~wait() {
> out.notify();
> mtx->exit();
> }
> mutex* mtx;
> condition in;
> condition out;
> };
> void enter();
> void exit();
> };
You've attempted to solve the problem for wait which was already
solved by passing in a lock instead of mutex, but have ignored the
notify().
We could extend the idea to notify, but for this to work it basically
requires that the mutex be recursive. Otherwise you have the
opposite problem we have now... the mutex would have to be unlocked
before you call notify().
I must admit that I'm still not convinced that we should have a non-
recursive mutex, but others feel differently. If we only had
recursive mutexes then notify() call could lock the mutex
internally. We'd probably still pass in a lock to wait() at this
point because the whole point is to have the mutex locked before and
after a call to wait. I'd like that solution, but it requires a
recursive mutex and would still leave us with one run time error
(namely passing in a lock that's not a lock on the associated
mutex). Personally, I can live with that run time error so maybe we
just need to convince people to only have recursive mutexes? ;)
Bill Kempf
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk