Boost logo

Boost :

From: Stefan Seefeld (seefeld_at_[hidden])
Date: 2003-06-07 09:40:03

William E. Kempf wrote:

>>so what ? the 'real' queue length is kept private and doesn't matter
>>much. It's the signaling of the semaphore that makes the change public.
> This is a race condition. It also occurs when extracting data from the
> queue. Whether or not the "'real' queue length" is private is not
> relevant, this race condition can lead to improper synchronization, such
> as trying to to extract data when there's no data left to extract.

Can you elaborate ? I can manipulate the queue as much as I want, the
availability of tasks will be known to consumers only when they are
signaled, not when the queue is non-empty. Where is the race condition ?
(Same argument for the empty slots)

Oh, of course the queue needs a mutex, too (as I said in my original mail),
just to protect the queue's internal structure, so a task extraction
may look like that:

template <typename T>
T task_queue::consume()
   my_tasks.wait(); // decrements 'tasks' counter
   Prague::Guard<Mutex> guard(my_mutex); // protects queue impl
   T t = rep_type::front(); // copies next task (mustn't throw !)
   rep_type::pop(); // removes task from queue impl; // announce availability of a free slot
   return t; // return t

The only tricky thing here is to make sure T's copy constructor doesn't throw.

>>And then there is the other semaphore I use to count the free slots,
>>which you didn't comment on, probably because it didn't fit into your
> No, actually, it strengthens the argument, because you now have even more
> state that needs to be synchronized to ensure against race conditions.

I don't understand this. The state in question is the difference between
the capacity of the queue and its current length. The only variable holding
this state is the semaphore ('my_free' in my code snippet). What do I need
to synchronize here ?


Boost list run by bdawes at, gregod at, cpdaniel at, john at