/* ------------------------------------------------------------------------
 *                            TestReadWrite.cpp
 * ------------------------------------------------------------------------
 *   Test driver for the ReaderWriter synchronization classes.
 *
 *  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.
 */

#include <windows.h>
#include <iostream>
#include "ReaderWriter.h"
#include "Event.h"


ReadWriteProtector  Protect;
AutoResetEvent      LockStep;   // Used to reduce startup conflicts
BOOL          bDie = FALSE;

const unsigned  NumReaders = 8;
const unsigned  NumWriters = 2;


DWORD  WINAPI   ReadThread( LPVOID lpvRW );
DWORD  WINAPI   WriteThread( LPVOID lpvRW );

int main( void )
 {
  HANDLE         Threads[NumReaders+NumWriters];
  DWORD          Dummy;
  int            ThreadNum=0;
  int            i;

  LockStep.Reset();
  for(i=0;i < NumReaders;++i,++ThreadNum)
   {
    Threads[ThreadNum] = CreateThread( NULL, 0, ReadThread, (LPVOID)&Protect,
                                       0, &Dummy );
    LockStep.Wait();
   }

  for(i=0;i < NumWriters;++i,++ThreadNum)
   {
    Threads[ThreadNum] = CreateThread( NULL, 0, WriteThread, (LPVOID)&Protect,
                                       0, &Dummy );
    LockStep.Wait();
   }

  for(i=0;i < ThreadNum;++i)
   {
    WaitForSingleObject( Threads[i], INFINITE );
   }

  return 0;
 }


void ReadIt( ReadWriteProtector &RW )
 {
  RWPReader sync(RW);
  cout << "Reading..." << endl;
 }

DWORD  WINAPI	ReadThread( LPVOID lpvRW )
 {
  ReadWriteProtector   *pRW = (ReadWriteProtector*)lpvRW;
  LockStep.Set();    // Release main thread

  while(!bDie)
   {
    ReadIt( *pRW );
   }

  return 0L;
 }



void WriteIt( ReadWriteProtector &RW )
 {
  RWPWriter sync(RW);

  char  ch;
  cout << "Writing...";
  cin >> ch;
  cout << " Completed" << endl;
  if('x' == ch)
    bDie = 1;
 }

DWORD  WINAPI   WriteThread( LPVOID lpvRW )
 {
  ReadWriteProtector   *pRW = (ReadWriteProtector*)lpvRW;
  LockStep.Set();    // Release main thread

  while(!bDie)
   {
    cout << "Waiting...";
    Sleep( 5000 );

    cout << " Ready" << endl;
    if(!bDie)
      WriteIt( *pRW );
   }
  return 0L;
 }
