src/object/barrier.cc
rObject
    Barrier::wait()
    {
      runner::Job& r = runner();
      value_type::iterator i =
        value_.insert(value_.end(), value_type::value_type(&r, rObject()));

      // No waiters are in the list, so mark it-self as the next waiter.
      if (rest_ == value_.end())
        rest_ = i;

      try
      {
        r.frozen_set(true);
        r.yield();

        // In no circumstances a signaled process could be marked as being a
        // waiter, this could only mean that the rest_ iterator has not been
        // correctly updated.
        aver(rest_ != i);

        // Regular wake up from a barrier wait.
        // Get the payload and remove us from the queue.
        rObject payload = i->second;
        value_.erase(i);
        return payload;
      }
      catch (...)
      {
        // In some rare cases when we receive a signal and an exception, the
        // payload is ignored and not forwarded to another waiter.  The
        // reason is to avoid getting his own signal back.  This differs
        // from the semaphore implementation.

        // Unfreeze the job.
        r.frozen_set(false);

        // Signal that we should no longer stay queued.  If the current
        // waiter is the next to be signaled, then skip it.  Remove it-self
        // from the list of waiters.
        if (rest_ == i)
          rest_++;

        // The erase operation should not go before the potential rest_
        // update, because this would invalidate the rest_ pointer.
        value_.erase(i);

        // Rethrow the exception received.
        throw;
      }
    }
// The rest_ iterator is used to keep track of the elements which are
// still waiting to receive a signal.  The left side of the rest_
// iterator are jobs that received a signal and that are waiting
// to get spawned.  The right side of rest_ iterator (included) are jobs
// waiting to get a signal.  Thus the rest_ iterator is
// pointing to the next job that should be signaled.
//
// The current implementation uses a list to queue jobs
// waiting to receive a signal.  A waiter is responsible to insert
// itself at the end and to remove itself from the list.
//
//  value_ |- - - signaled - - - - - - waiters - - - -|
//                             ^
//                           rest_
//
// When the rest_ iterator is at the end, no jobs are waiting on
// the barrier.
The rest_ iterator is used to keep track of the elements which are
still waiting to receive a signal.  The left side of the rest_
iterator are jobs that received a signal and that are waiting
to get spawned.  The right side of rest_ iterator (included) are jobs
waiting to get a signal.  Thus the rest_ iterator is
pointing to the next job that should be signaled.

The current implementation uses a list to queue jobs
waiting to receive a signal.  A waiter is responsible to insert
itself at the end and to remove itself from the list.



When the rest_ iterator is at the end, no jobs are waiting on
the barrier.
The rest_ iterator is used to keep track of the elements which are still waiting to receive a signal . The left side of the rest_ iterator are jobs that received a signal and that are waiting to get spawned . The right side of rest_ iterator ( included ) are jobs waiting to get a signal . Thus the rest_ iterator is pointing to the next job that should be signaled . The current implementation uses a list to queue jobs waiting to receive a signal . A waiter is responsible to insert itself at the end and to remove itself from the list . When the rest_ iterator is at the end no jobs are waiting on the barrier .
rObject
    Barrier::wait()
    {
      runner::Job& r = runner();
      value_type::iterator i =
        value_.insert(value_.end(), value_type::value_type(&r, rObject()));
      if (rest_ == value_.end())
        rest_ = i;
      try
      {
        r.frozen_set(true);
        r.yield();
        aver(rest_ != i);
        rObject payload = i->second;
        value_.erase(i);
        return payload;
      }
      catch (...)
      {
        r.frozen_set(false);
        if (rest_ == i)
          rest_++;
        value_.erase(i);
        throw;
      }
    }
rObject Barrier :: wait ( ) { runner :: Job & r = runner ( ) ; value_type :: iterator i = value_ . insert ( value_ . end ( ) , value_type :: value_type ( & r , rObject ( ) ) ) ; if ( rest_ == value_ . end ( ) ) rest_ = i ; try { r . frozen_set ( true ) ; r . yield ( ) ; aver ( rest_ != i ) ; rObject payload = i -> second ; value_ . erase ( i ) ; return payload ; } catch ( ... ) { r . frozen_set ( false ) ; if ( rest_ == i ) rest_ ++ ; value_ . erase ( i ) ; throw ; } }
The rest_ iterator is used to keep track of the elements which are
still waiting to receive a signal.
The rest_ iterator is used to keep track of the elements which are still waiting to receive a signal .
// No waiters are in the list, so mark it-self as the next waiter. // In no circumstances a signaled process could be marked as being a // waiter, this could only mean that the rest_ iterator has not been // correctly updated. // Regular wake up from a barrier wait. // Get the payload and remove us from the queue. // In some rare cases when we receive a signal and an exception, the // payload is ignored and not forwarded to another waiter.  The // reason is to avoid getting his own signal back.  This differs // from the semaphore implementation. // Unfreeze the job. // Signal that we should no longer stay queued.  If the current // waiter is the next to be signaled, then skip it.  Remove it-self // from the list of waiters. // The erase operation should not go before the potential rest_ // update, because this would invalidate the rest_ pointer. // Rethrow the exception received.