Boost logo

Threads-Devel :

From: Stuart A. Malone (samalone_at_[hidden])
Date: 2006-12-14 16:55:29


I was looking at the boost::barrier class a couple of days ago, and
had an idea for a possible improvement that I wanted to share and get
some feedback on.

I've been working on a Mac OS X application that needs to suspend the
UI for a time while one or more worker threads perform a background
computation for Sync Services. Once all the worker threads have
completed, the UI thread can resume processing events. To resume the
UI thread, exactly one of the worker threads needs to call
QuitEventLoop() once all of the worker threads have completed.

The boost::barrier class seems like a natural way to implement this,
except that it needs to know the number of threads when it is
constructed. In my case, the worker threads are launched in response
to system callbacks, and it is not easy to know in advance how many
threads will be created.

This made me think that the barrier class needed an additional member
function to increment the thread count. But as soon as I thought of
this, I realized that the increment calls needed to be balanced by an
equal number of wait calls, and so it occurred to me that this would
be best implemented by a barrier::scoped_wait class whose constructor
incremented the thread count, and whose destructor called wait().
This would have the advantages that threads could register with the
barrier object after it had been created, and there would be a
reduced risk of deadlock if a thread threw an exception before
calling wait().

The main problem I see with this approach is that the destructor for
the barrier::scoped_wait class would not be able to return a boolean
value like the existing wait() function does, but there are ways
around this. The scoped_wait class could have its own wait()
function that returns a boolean, which would cause the wait() to
occur before the destruction of the scoped_wait object. The barrier
wait() logic would need to be enhanced so that it preferred to return
true from an explicit call to wait() rather than a destructor call.
The consequence would be that only threads that explicitly called wait
() would be eligible to receive a true result, while threads that
threw exceptions or relied on the destruction of the scoped_wait
object would not be.

It seems to me that a barrier::scoped_wait class would be more
flexible than having to predict the number of threads in advance, and
less prone to deadlock than having each thread call barrier::wait()
directly.

Thoughts?

--Stuart A. Malone
   Llamagraphics, Inc.
   Makers of Life Balance personal coaching software
   http://www.llamagraphics.com/


Threads-Devel list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk