Provided by: libbobcat-dev_4.01.03-2ubuntu1_amd64 bug

NAME

       FBB::SharedCondition - Shared Memory Condition Variable

SYNOPSIS

       #include <bobcat/sharedcondition>
       Linking option: -lpthread, -lbobcat

DESCRIPTION

       Condition variables are used to synchronize threads based on the values of data. Condition
       variables allow threads to wait until a certain condition has occurred,  after  which  the
       threads  continue  their actions. Thus waiting threads don’t continuously have to poll the
       state of a variable (requiring the threads to gain access to the variable before they  can
       inspect  its  value). Using condition variables waiting threads simply wait until they are
       notified.

       SharedCondition objects can be used in combination  with  shared  memory.  SharedCondition
       objects interface to objects (called Condition objects in this man-page) which are defined
       in shared memory and contain a SharedMutex and a shared condition object. These  Condition
       objects  may  be  accessed  by  threads  running  in  different processes. These different
       processes might run a single main thread, or they themselves can be multi-threaded.

       Condition variables are used in situations like these:

       o      There exists a thread which should be suspended until a certain condition has  been
              met.

       o      This thread locks a mutex (or waits until the lock has been obtained)

       o      While  the  condition  hasn’t  been  met,  the  thread  is suspended (i.e., waits),
              automatically releasing the mutex’s lock.

       o      Somehow (see  below)  the  thread  is  resumed,  at  which  point  the  thread  has
              automatically reacquired the lock.

       o      Once  the  condition  has  been  met,  the while loop ends, and the mutex’s lock is
              released.

       o      There exists a second thread, which influences the variables that are  elements  of
              the condition, and which may notify the waiting thread, once the required condition
              has been met.

       o      This second thread locks the same mutex as used by the first thread.

       o      The second thread modifies the variables that are involved,  and  if  the  required
              condition has been met, it notifies the first thread.

       o      The  second  thread  releases the mutex’s lock, allowing the first thread to obtain
              the mutex’s lock.

       While the first thread is waiting, it is suspended. It may be resumed when it  receives  a
       notification  from  another  thread,  but  also  for spurious reasons. Therefore the first
       thread must verify that the condition has been met after resuming its actions.

       As  condition  variables  are  always  used  in  combination  with  a  mutex,  SharedMutex
       encapsulates  the  mutex-handling. The software using SharedCondition objects doesn’t have
       to handle the mutex itself.

       SharedCondition objects are used to synchronize  actions  by  different  processes,  using
       shared  memory  as  their  vehicle  of synchronization/communication. The actual condition
       variable  that  is  used  by  a  SharedCondition  object  is  defined  in  shared  memory.
       SharedCondition objects themselves are small objects, containing the necessary information
       to access the actual shared memory condition variable.

NAMESPACE

       FBB
       All constructors, members, operators and manipulators, mentioned  in  this  man-page,  are
       defined in the namespace FBB.

INHERITS FROM

       SharedMutex(3bobcat)

CONSTRUCTORS, DESTRUCTOR

       o      SharedCondition():
              The  default  constructor  creates  an  empty  stub which cannot yet be used (or an
              FBB::Exception  is  thrown).  As  the  SharedCondition  class  supports  assignment
              operators,  empty  stubs  can  easily  be  (re)configured  at  any time after their
              construction.

       o      ~SharedCondition():
              The class’s destructor releases (if applicable) its lock on  the  shared  condition
              variables  mutex  lock.  The  destructor  takes no action if its object is an empty
              stub.  (Default) copy and move constructors are available.

OVERLOADED OPERATORS

       The (default) overloaded move and copy assignment operators are available.

MEMBER FUNCTIONS

       Returning from SharedCondition member functions the offset of the SharedMemory  object  in
       which  the  condition  variable  has been defined has not changed. Internally, the current
       offset is saved; the requested function is performed; and the original offset is restored.
       Consequently, SharedCondition member functions can be used disregarding the SharedMemory’s
       current offset.

       o      void lock() const:
              When returning from this member, the current process has locked the SharedCondition
              object.  Be careful not to call lock twice during the same thread of execution (cf.
              sharedmutex(3bobcat) for details).

       o      void notify() noexept:
              One of the threads waiting on the  SharedCondition  object  wakes  up.  The  thread
              calling notify should release its mutex lock shortly after calling notify, allowing
              the notified thread to obtain  the  lock.  A  prototypical  piece  of  pseudo  code
              illustrating the use of notify looks like this:

                  sharedCondition.lock();     // lock the mutex
                  ...                         // operate on the condition’s variables
                  if (conditionWasMet)        // ready to notify
                      sharedCondition.notify();
                  sharedCondition.unlock();   // release the lock

              As  the  sharedCondition.lock  ...  sharedCondition.unlock  sequence  itself may be
              executed at different flow of control sections, the unlock member cannot be  called
              from within notify.

       o      void notifyAll() noexept:
              Different  from  the  plain  notify member, this member wakes up all of the threads
              waiting on the SharedCondition  object.  However,  after  the  current  thread  has
              released its mutex lock only one of these signaled threads will actually obtain the
              lock. The pseudo code for using notifyAll is identical to the pseudo code for using
              notify (i.e., calling notifyAll, of course).

       o      std::streamsize offset() const:
              The  location  of the shared condition variable (within the SharedMemory object) is
              returned. The shared condition object ends at offset() +  SharedCondition::width(),
              see below.

       o      void unlock() const:
              The  object’s  lock  is released (nothing happens if called when the current object
              does not have the object’s  lock).

       o      void wait():
              Before calling wait  the  current  thread  should  have  obtained  a  lock  on  the
              SharedCondition object.

              When  calling wait the running thread suspends its activities and waits until being
              notified. Once notified, it reacquires the lock and continues. Shortly  after  this
              the  process  should again release its lock on the SharedCondition object.  lock. A
              prototypical piece of pseudo code illustrating how to use wait looks like this:

                  sharedCondition.lock();         // lock the mutex
                  while (conditionWasNotYetMet)   // waiting required
                      sharedCondition.wait();
                  ...                             // do something: we have the lock
                  sharedCondition.unlock();       // release the lock

       o      void wait(Predicate pred):
              This member was implemented as a member template. Predicate either is  a  predicate
              function  or  a  predicate function object. The predicate function or the predicate
              function object’s function call operators may not require  arguments.  As  long  as
              pred is returning false, wait() (no arguments) is called. The function returns once
              pred has returned true.

              The running thread should have obtained a lock  on  the  SharedCondition  condition
              variable  prior  to  calling  this  member,  and should release the lock after this
              member has returned.

              The pseudo code for using wait(pred) is identical to the pseudo code for using wait
              (albeit that pred has to be passed to wait, of course).

       o      std::cv_status wait_for(std::chrono::duration<Type, Unit> const &relTime):
              This  member  was  implemented  as  a member template. Type defines the type of the
              variable holding the amount of time (usually int64_t), specified in time unit Unit.
              Predefined  duration  types  are  available  from  the  std::chrono namespace, like
              std::chrono::seconds(4), representing 4 seconds, or  std::chrono::milliseconds(30),
              representing 30 milliseconds.

              The  running thread should have obtained a lock on SharedCondition prior to calling
              this member, and should release the lock after this member has returned.

              This member acts like wait, returning std::cv_status::no_timeout if a  notification
              was  received  before  relTime  has  passed.  Otherwise  std::cv_status::timeout is
              returned.

              A prototypical piece of pseudo code illustrating how to  use  wait_for  looks  like
              this:

                  sharedCondition.lock();         // lock the mutex
                  while (conditionWasNotYetMet)   // waiting required
                  {
                      while (sharedCondition.wait_for(someTime)
                             == std::cv_status::timeout)
                          handle_timeout

                      do_something
                  }
                  sharedCondition.unlock();       // release the lock

              When returning from wait_for the current thread has obtained the shared condition’s
              lock, but maybe due to a timeout: this can be  verified  by  inspecting  wait_for’s
              return value, and an appropriate action can be selected.

       o      bool wait_for(std::chrono::duration<Type, Unit> const &relTime, Predicate pred):
              This  member  was  implemented  as  a member template. Type defines the type of the
              variable holding the amount of time (usually int64_t), specified in time unit Unit.
              Predicate  either  is  a  predicate  function  or a predicate function object.  The
              predicate function or the predicate function object’s function call  operators  may
              not require arguments.

              The  running thread should have obtained a lock on SharedCondition prior to calling
              this member, and should release the lock after this member has returned.

              As long as pred returns false, wait_for(relTime) is called. If the latter  function
              returns  std::cv_status::timeout,  then  pred  is  called,  and its return value is
              returned. Otherwise true is returned.

              The pseudo code for using this member is identical to the pseudo code for using the
              abovementioned  wait_for  member (albeit that pred must also be passed to wait_for,
              of course).

       o      std::cv_status wait_until(std::chrono::time_point<Clock, Duration> const &absTime):
              This member has been implemented as a member template. Clock defines the clock-type
              to use (usually std::chrono::system_clock), Duration is the type name of a duration
              type (as used with wait_for). E.g., to specify 5 seconds  after  the  current  time
              this member could be called like this:

                  std::chrono::system_clock::now() + std::chrono::seconds(5)

              The  running thread should have obtained a lock on SharedCondition prior to calling
              this member, and should release the lock after this member has returned.

              This member acts like wait_for(relative-time), returning std::cv_status::no_timeout
              if   a   notification   was   received   before   absTime   has  passed.  Otherwise
              std::cv_status::timeout is returned.

              The pseudo code for using this member is identical to the pseudo code for using the
              abovementioned  wait_for(relative-time)  member  (albeit that absolute time must be
              specified).

       o      bool wait_until(std::chrono::time_point<Clock, Duration> const &absTime,  Predicate
              pred):
              This  member  was  implemented  as  a  member  template.  Clock and Duration define
              identical types as mentioned  at  the  previous  member.   Predicate  either  is  a
              predicate function or a predicate function object (not expecting arguments).

              The  running thread should have obtained a lock on SharedCondition prior to calling
              this member, and should release the lock after this member has returned.

              As long as pred  returns  false,  wait_until(absTime)  is  called.  If  the  latter
              function returns std::cv_status::timeout, then pred is called, and its return value
              is returned. Otherwise true is returned.

              The pseudo code for using this member is identical to the pseudo code for using the
              abovementioned  wait_until  member  (albeit  that  pred  must  also  be  passed  to
              wait_until, of course).

STATIC MEMBER FUNCTIONS

       o      SharedCondition  &attach(SharedMemory  &shmem,  std::ios::off_type  offset   =   0,
              std::ios::seekdir origin = std::ios::beg):
              The  SharedCondition object interfacing to the shared condition variable located at
              offset (relative to origin) in shmem is returned.

              An FBB::Exception is thrown if the requested offset is invalid (i.e., smaller  than
              0 or exceeding shmem.maxOffset()).

       o      FBB::SharedCondition create(SharedMemory &shmem):
              A   shared  condition  variable  is  initialized  at  the  current  offset  of  the
              SharedMemory object referred to by shmem, or  at  the  first  offset  of  the  next
              physical shared data segment.

              A  SharedCondition  object interfacing to the initialized shared condition variable
              is returned.

              An FBB::Exception  is  thrown  if  there  isn’t  enough  memory  available  in  the
              SharedMemory object to define a shared condition variable.

       o      size_t size() const:
              Returns  the size in bytes of the shared condition variables stored in SharedMemory
              objects.

EXAMPLE

       #include <iostream>

       #include <bobcat/sharedcondition>
       #include <bobcat/sharedmemory>

       using namespace std;
       using namespace FBB;

       int main(int argc, char **argv)
       try
       {
           if (argc == 1)
           {
               cout <<
                   "Argument:\n"
                   "   c: create a shared memory segment + SharedCondition "
                                                           ", display ID\n"
                   "   k <id>: kill shared memory segment <id>\n"
                   "   m <id>: show a message every 5 secs, otherwise wait until\n"
                   "           being notified in segment <id>\n"
                   "   n <id>: notify the SharedCondition in segment ID <id>\n"
               ;
               return 0;
           }

           switch (argv[1][0])
           {
               case ’c’:
               {
                   SharedMemory shmem(1, SharedMemory::kB);

                   SharedCondition cond = SharedCondition::create(shmem);

                   void *ptr = shmem.ptr();

                   cout << "ID = " << shmem.id() << ", SharedCondition at " <<
                           cond.offset() << endl;
                   break;
               }

               case ’k’:
               {
                   SharedMemory shmem(stoll(argv[2]));
                   shmem.kill();
                   break;
               }

               case ’m’:
               {
                   SharedMemory shmem(stoll(argv[2]));
                   SharedCondition cond = SharedCondition::attach(shmem);

                   cond.lock();
                   cout << "Obtained the lock. Now waiting for a notification\n";

                   while (true)
                   {
                       switch (cond.wait_for(chrono::seconds(5)))
                       {
                           case cv_status::timeout:
                               cout << "Waited for 5 seconds\n\n";
                           break;

                           case cv_status::no_timeout:
                               cond.unlock();
                               cout << "Received the notification. Unlocked.\n";
                           return 0;
                       }
                   }
               }

               case ’w’:
               {
                   SharedMemory shmem(stoll(argv[2]));
                   SharedCondition cond = SharedCondition::attach(shmem);

                   cond.lock();
                   cout << "Obtained the lock. Now waiting for a notification\n";

                   cond.wait();
                   cout << "Received the notification. Unlocking.\n";

                   cond.unlock();
                   break;
               }

               case ’n’:
               {
                   SharedMemory shmem(stoll(argv[2]));

                   SharedCondition cond = SharedCondition::attach(shmem);

                   cout << "Notifying the other after Enter ";
                   cin.ignore(1000, ’\n’);

                   cond.lock();
                   cout << "Obtained the lock. Now notifying the other\n";
                   cond.notify();
                   cout << "Sent the notification. Now unlocking.\n";
                   cond.unlock();
                   break;
               }

           }
       }
       catch (exception const &exc)
       {
           cout << "Exception: " << exc.what() << endl;
       }

FILES

       bobcat/sharedcondition - defines the class interface

SEE ALSO

       bobcat(7)    isharedstream(3bobcat),     osharedstream(3bobcat),     sharedblock(3bobcat),
       sharedmemory(3bobcat),  sharedpos(3bobcat), sharedreadme(7bobcat), sharedsegment(3bobcat),
       sharedstream(3bobcat), sharedstreambuf(3bobcat)

BUGS

       None Reported.

DISTRIBUTION FILES

       o      bobcat_4.01.03-x.dsc: detached signature;

       o      bobcat_4.01.03-x.tar.gz: source archive;

       o      bobcat_4.01.03-x_i386.changes: change log;

       o      libbobcat1_4.01.03-x_*.deb: debian package holding the libraries;

       o      libbobcat1-dev_4.01.03-x_*.deb: debian package holding the libraries,  headers  and
              manual pages;

       o      http://sourceforge.net/projects/bobcat: public archive location;

BOBCAT

       Bobcat is an acronym of `Brokken’s Own Base Classes And Templates’.

COPYRIGHT

       This  is  free  software,  distributed  under  the terms of the GNU General Public License
       (GPL).

AUTHOR

       Frank B. Brokken (f.b.brokken@rug.nl).