I'm trying to get familiar with boost threads, and I was going through
vutil's synqueue.hh and something didn't make sense to me...

let's say that you have an empty queue, and two threads try to call
popOrWait at the same time:

        Element popOrWait() {
            boost::mutex::scoped_lock l(lk);
            if(thequeue.empty()) cond.wait(l);
            Element e = thequeue.front();
            thequeue.pop_front();
            return e;
        }

Ok, so the first one gets the lk mutex, sees the queue is empty, and waits
on the condition, simultaneously releasing the mutex. The second thread then
gets the mutex and also waits on the condition.

Let's say then a third thread comes along and adds one element to the queue
with a push:

        void push(Element e) {
            boost::mutex::scoped_lock l(lk);
            thequeue.push_back(e);
            cond.notify_all();
        }

Upon the notify_all(), both the previous threads will wake up and try to
re-acquire the lk lock. One will succeed, pop the value off the queue, and
exit, releasing the lock. Then the other will get the lock and try to pop a
value off a now-empty-again queue!

This seems like a problem... shouldn't popOrWait be something more like
while(thequeue.empty()) cond.wait(l);? And why use a notify_all rather than
notify_one? (Though some googling has revealed that notify_one might not
guarantee that only one gets notified -- just that at *least* one gets
notified -- at least on a pthreads-based platform. See
http://www.opengroup.org/onlinepubs/009695399/functions/pthread_cond_signal.html
 down under "Multiple Awakenings by Condition Signal")

- Ken


_______________________________________________
vos-d mailing list
vos-d@interreality.org
http://www.interreality.org/cgi-bin/mailman/listinfo/vos-d

Reply via email to