//=========================================================================
// Summary  : */
// Filename : Fork.h
// Author   : */
// Project  : */
// Revision : 1
// Created  : 2001/01/22
// Modified : 2001/01/22
//=========================================================================
// Description :
//=========================================================================
#ifndef _FORK_H
#define _FORK_H

#include "MyAssert.h"
#include "ourTypes.h"
/*
CLASS 
Fork

DESCRIPTION
The Fork class wraps the fork() function.  The constructor inits everything,
and then the user explicitly calls the "Fork::run()" function.

After (and during) the "run()" call, there are two
near-identical copies of the code running as separate threads/processes.  The
only difference between the two copies is held in the Fork class.  One copy is 
considered the "parent" and one copy is considered the "child."

A common idiom is to run a minor looping thread inside the runChild() function-
The call simply never returns, and you can create very different functionality in
the two processes.  If you create the Fork object early in your program's execution,
then you do not waste many system resources on the child.

AUTHOR
Andrew Grant
*/
class Fork {

 public:

  ///////////////////////////////////////////////////////////////////
  // Constructor
  Fork();

  ///////////////////////////////////////////////////////////////////
  // Destructor
  virtual ~Fork();

  ///////////////////////////////////////////////////////////////////
  // Forks the process and calls specific runXXX() functions
  void run();

  ///////////////////////////////////////////////////////////////////
  // Which am I?
  bool bIsParent() const  {return _bIsParent;};
  bool bIsChild() const   {return !_bIsParent;};

  bool bSucceeded() const {return _bSuccess;};

 protected:

  ///////////////////////////////////////////////////////////////////
  // Run main processing loop
  virtual void runParent();
  virtual void runChild();

  ///////////////////////////////////////////////////////////////////
  // Safety precaution to make sure that we are in the right place.
  //  Call in every function that should only happen in the correct 
  //  thread.
  void VerifyParent() { Assert(_bSuccess); Assert(_bIsParent); };
  void VerifyChild() { Assert(_bSuccess); Assert(!_bIsParent); };

  


  bool _bSuccess;   // true if the fork worked.
  bool _bRunCalled; // true if "run()" has ever been called.
  bool _bIsParent;  // true IFF we are the parent.
  int  _pidChild;   // pid of the child.
  int  _pidParent;  // pid of the parent.
};

#endif
