|
Boost : |
From: William Kempf (sirwillard_at_[hidden])
Date: 2000-08-19 10:09:25
--- 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...>
> > > > --- In boost_at_[hidden], "Greg Colvin" <gcolvin_at_u...> wrote:
> > > > ...
> > > > > 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().
> > >
> > > What problem with notify() have I not solved? I've
> > > set it up so that notify() is called only inside the
> > > mutex. I left it without saying that during the calls
> > > to wait() and notify() the lock (or locks) on the mutex
> > > must be temporarily released.
> >
> > I missed the call to notify() in the destructor of wait. I asked
you
> > once before why you'd do that, and it makes even less sense here.
>
> Makes perfect sense to me. See the example code below.
>
> > You've set it up so the only way to notify a condition is by
first
> > waiting on a second condition. I don't see how this would even
> > work. Who would notify your "in" condition? How would they
insure
> > at compile time that the mutex was locked? I see nothing solved
here
> > and see little purpose in having an "out" condition.
>
> Typically the conditions start out signaled, so the very
> first attempt to wait on them returns immediately.
This is not good. In your example below that means that notempty is
signaled to begin with, but we are empty.
> > BTW, notify() does *NOT* temporarily release the mutex.
>
> Right, sorry.
>
> Here is the classic two-condition example, where after waiting on
> nonfull you need to notify nonempty, and after waiting on nonempty
> you need to notify nonfull.
>
> class buffer : mutex {
> int p,c,n;
> vector<int> buf;
> condition nonfull, nonempty;
> public:
> buffer(int n) : p(0),c(0),n(0),buf(n){}
> void send (int m) {
> wait entry(this,(free1 == buf.size())(n),nonfull,nonempty);
> buf[p] = m;
> p = (p+1)%buf.size();
> ++n;
> }
> int receive() {
> wait entry(this,(free1 == 0)(n),nonempty,nonfull);
> int i = buf[c];
> c = (c+1)%buf.size();
> --n;
> return i;
> }
> };
And if we have only one condition? What will you do then, use an
artificial second condition just to satisfy the need for two
conditions? What if we have three conditions we must wait on?
Again, I see no purpose to signal a second condition on exit of the
wait in a general fashion. It may work in some specific cases, but
it's pointless in most.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk