Boost logo

Boost :

From: Greg Colvin (gcolvin_at_[hidden])
Date: 2000-08-18 15:47:40


From: "William Kempf" <sirwillard_at_[hidden]>
> --- 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.
 
> 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;
      }
   };


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk