//*********************************************************************
// thread.h
// Copyright © 2002 Paul J Medlock
//*********************************************************************

#ifndef THREAD_H
#define THREAD_H

#ifndef FARBASE_H
#include "atom.h"
#include "list.h"
#endif

//=====================================================================
// mutual exclusion protection
//
_FBDEF(CSemaphore)
class FBC_USE CSemaphore: public CAtom {
   public:
      FB_USE CSemaphore(short _start = 0, short _size = 1);
      virtual FB_USE ~CSemaphore();

      virtual FB_USE_(short) Ima(void);
      virtual FB_USE_(Pchar) IAm(void);
      virtual FB_USE_(bool)  Isa(const short _type);

      virtual FB_USE_(ulong) Wait(void);
      virtual FB_USE_(ulong) Release(void);

   protected:
#if   defined(FV_MSWIN16)
   #warning Semaphore not supported

#elif defined(FV_MSWIN32)
      HANDLE m_hSema4;

#elif defined(FV_MACINTOSH)
   #warning FV_MACINTOSH TBD

#elif defined(FV_UNIX)
   #warning FV_UNIX TBD

#endif // FV_UNIX
   }; // CSemaphore

//=====================================================================
// supplier vs consumer
//
_FBDEF(CPort)
class FBC_USE CPort: public CAtom {
   public:
      FB_USE CPort(short _size);
      virtual FB_USE ~CPort();

      virtual FB_USE_(short) Ima(void);
      virtual FB_USE_(Pchar) IAm(void);
      virtual FB_USE_(bool)  Isa(const short _type);

      FB_USE_(bool)   Empty  (void);
      FB_USE_(ulong)  Number (void) { return list->Number(); }

      FB_USE_(void)   Send   (RPCItem _item);
      FB_USE_(PCItem) Receive(void);

   protected:
      PCSemaphore s1;
      PCSemaphore s2;
      PCSemaphore s3;
      PCList      list;
   }; // CPort

//=====================================================================
// restrict access to code
//
_FBDEF(CCriticalSection)
class FBC_USE CCriticalSection: public CAtom {
   public:
      FB_USE CCriticalSection(void);
      virtual FB_USE ~CCriticalSection();

      virtual FB_USE_(short) Ima(void);
      virtual FB_USE_(Pchar) IAm(void);
      virtual FB_USE_(bool)  Isa(const short _type);

      virtual FB_USE_(void) Enter(void);
      virtual FB_USE_(void) Leave(void);

   protected:

#if   defined(FV_MSWIN16)
   #warning Critical Section not supported

#elif defined(FV_MSWIN32)
      CRITICAL_SECTION m_cs;

#elif defined(FV_MACINTOSH)
   #warning FV_MACINTOSH TBD

#elif defined(FV_UNIX)
   #warning FV_UNIX TBD

#endif // FV_UNIX
   }; // CCriticalSection

//=====================================================================
// Independent operation - separate stack, common data
//
_FBDEF(CThread)
class FBC_USE CThread: public CItem {
   public:
      FB_USE CThread(short _size = 8);
      virtual FB_USE ~CThread();

      virtual FB_USE_(short) Ima(void);
      virtual FB_USE_(Pchar) IAm(void);
      virtual FB_USE_(bool)  Isa(const short _type);

#ifndef _SLANGER
      FB_USE_(ulong) Start(ulong _sizeStack = 0);
      FB_USE_(void)  Stop (void);
      virtual
      FB_USE_(void)  Run  (void);
      FB_USE_(void)  Log  (char _flag, Pchar _format, ...);
#endif // _SLANGER

      FB_USE_(PCPort) GetPort(void) { return port; }

      FB_USE_(ulong)  GetID(void) { return id; }

   protected:
    static void   run(void *_arg);

      static ushort threads;

      ulong  id;
      PCPort port;
      bool   started;
//?   ulong  then;
  }; // CThread

#endif // THREAD_H