Man Page stream_locker.3




NAME

     stream_locker - class used for application level locking  of
     iostream class objects.


SYNOPSIS

     #include <rlocks.h>

     class stream_locker {
     public:
          enum lock_choice { lock_defer=0, lock_now=1  };
          stream_locker(stream_MT&, lock_choice lock_flag=lock_now);
          stream_locker(stream_MT*, lock_choice lock_flag=lock_now);
          stream_locker(stream_rmutex&, lock_choice lock_flag=lock_now);
          stream_locker(stream_rmutex*, lock_choice lock_flag=lock_now);
          ~stream_locker();
          void lock();
          void unlock();
     };




DESCRIPTION

     Instances of class stream_locker are used  to  implement  an
     atomic  sequence  of  operations on a iostream class object.
     The class stream_locker is a new feature of the multi-thread
     (MT)  safe libC. It can be used to define a region of mutual
     exclusion in which only one thread can perform operations on
     an iostream object at any one time.

     A stream_locker object applies on a per thread  basis.  When
     one  thread  in  a  process  locks  an iostream object other
     threads are  blocked  while  trying  to  use  that  iostream
     object.  The  scope of a stream_locker object can be used to
     define  the  bounds  of  the  mutual  exclusion  region.   A
     stream_locker  should  only  be  created  locally. It is not
     recommended to create a stream_locker with global or  static
     scope.

     When a stream_locker object is  created  locally,  its  con-
     structor  defines  the  beginning  of  the  mutual exclusion
     region and the destructor defines the  end  of  the  region.
     Alternatively  lock() and unlock() member functions are pro-
     vided to define explicitly the bounds of a mutual  exclusion
     region.


  Constructors
     stream_locker(stream_MT&, lock_choice lock_flag=lock_now);
     stream_locker(stream_MT*, lock_choice lock_flag=lock_now);

          All iostream classes in the MT safe version of libC are
          derived  from class stream_MT. The constructor does the
          locking for the stream given as an argument.

          The lock-choice flag indicates how the mutual exclusion
          region  is  to  be defined. A value of lock_defer indi-
          cates that the region is to be defined  by  the  lock()
          and  unlock()  member  functions.  A  value of lock_now
          indicates that the region is defined by the constructor
          and  destructor  of stream_locker. The default value of
          the lock_choice is lock_now.

     stream_locker(stream_rmutex&,                    lock_choice
     lock_flag=lock_now);           stream_locker(stream_rmutex*,
     lock_choice lock_flag=lock_now);

          Class stream_rmutex is the recursive mutex used by ios-
          tream  classes. It is not available for use by applica-
          tions.

  Member functions
     void lock();
     void unlock();
     Examples:

     In this first example a stream_locker object ensures that  a
     seek  to  a  particular offset in a file and a read from the
     file is atomic and there is no possibility of another thread
     changing  the  file  offset before the original thread reads
     the file.

     {    fstream fs;
          stream_locker s_lock(fs); // lock the stream fs
          . . . . .// open file
          fs.seekg(offset, ios::beg);
          fs.read(buf, len);
     }
     The constructor of object s_lock locks the fstream object fs
     and the destructor, executed at end of scope, unlocks fs.

     The second example illustrates the use of  explicit  defini-
     tion  of  the  mutual  exclusion  region  using  lock()  and
     unlock() member function calls of a stream_locker object.

     const int bufsize = 256;
     void print_tagged_lines(char *filename, int thread_tag) {
          char ibuf[bufsize+1];
          stream_locker  lockout(cout, stream_locker::lock_defer);
          ifstream instr(filename);

          while(1) {
               // read a line at a time
               instr.getline (ibuf, bufsize, '\n');
               if (instr.eof())
                    break;
               // lock cout stream so the i/o operation is atomic
               lockout.lock();
               // tag line and send to cout
               cout << thread_tag << ibuf << "\n";
               lockout.unlock();
          }
     }



ERRORS

     Stream_locker class objects are bracketing so if the end  of
     a  mutual  exclusion  region  is  not  defined implicitly or
     explicitly it is a user  error  and  the  result  cannot  be
     determined.