/* ========================================================================
 *                            ReaderWriter.h
 * ------------------------------------------------------------------------
 *  Interface file for the ReaderWriter classes, ReadWriteProtector,
 *    RWPReader, and RWPWriter.
 *
 *  Copyright 1997-1998 by G. Wade Johnson (Telescan, Inc.)
 *   Use of this code is placed in the public domain as long as the
 *   copyright notice is retained.
 */

#if !defined( INCLUDED_READERWRITER )
  #define  INCLUDED_READERWRITER

  #if !defined( INCLUDED_WINDOWS )
    #include <windows.h>
    #define INCLUDED_WINDOWS
  #endif
  #if !defined( INCLUDED_SYNCWRAPPER )
    #include "SyncWrapper.h"
  #endif
  #if !defined( INCLUDED_STRING )
    #include <string>
    #define INCLUDED_STRING
  #endif

  class  CriticalSection;
  class  ManualResetEvent;
  class  AutoResetEvent;


  class ReadWriteProtector
   {
    short             myNumReaders;
    short             myNumWriters;
    std::string       myName;
    CriticalSection   *mypTurnMutex;
    AutoResetEvent    *mypResourceProtect;
    ManualResetEvent  *mypMoreReadsAllowed;

   public:
    ReadWriteProtector();                   // create Mutexes/Events
    ReadWriteProtector( const char *name ); // create Mutexes/Events
    ~ReadWriteProtector();                  // close Mutexes/Events

    const std::string &getName() const { return myName; }

    void    BeginRead();
    void    EndRead();

    void    BeginWrite();
    void    EndWrite();
   } ;


  class RWPReader : public SyncWrapper<ReadWriteProtector>
   {
   public:
    RWPReader( ReadWriteProtector &rw )
     : SyncWrapper<ReadWriteProtector>(rw,
                   ReadWriteProtector::BeginRead,ReadWriteProtector::EndRead)
     { }
    ~RWPReader() { }
   } ;


  class RWPWriter : public SyncWrapper<ReadWriteProtector>
   {
   public:
    RWPWriter( ReadWriteProtector &rw )
     : SyncWrapper<ReadWriteProtector>(rw,
                   ReadWriteProtector::BeginWrite,ReadWriteProtector::EndWrite)
     { }
    ~RWPWriter() { }
   } ;

#endif
