Cross-Platform Design Strategies
by Bob Krause


Listing One
#if defined(WINDOWS)
  typedef CWinThread CNeoThreadBase; // MFC's thread class
  // The base class of all application threads is Neo's MFC thread class
  typedef CNeoThreadMFC CNeoThreadNative;
#elif defined(macintosh)
  typedef LThread CNeoThreadBase; // PowerPlant's thread class
  // The base class of all application threads is Neo's PP thread class
  typedef CNeoThreadPP CNeoThreadNative;
#endif


Listing Two
class CNeoThread : public CNeoThreadBase {
public:
  CNeoThread(void **aArg,
  const NeoThreadOptions aOptions,
  const NeoPriority aPriority);
  virtual ~CNeoThread(void);

  virtual void block(CNeoSemaphoreNative *aSemaphore, const long aParam,
                     const NeoTime aTime = kNeoForever) = 0;
  virtual NeoThreadState getState(void) const = 0;
  virtual long run(void);
  virtual void setState(const NeoThreadState aState,
                        const NeoThreadID aNext = kNeoNoThread) = 0;
  void suspend(void) = 0;
  virtual void unblock(CNeoSemaphoreNative *aSemaphore) = 0;
  virtual void yield(CNeoThread *aTo = nil) = 0;
protected:
  NeoThreadOptions fOptions;
};


Listing Three
extern CRITICAL_SECTION gNeoCritical;
class CNeoThreadMFC : public CNeoThread {
public:
  CNeoThreadMFC(NeoThreadOptions aOptions,
                const NeoPriority aPriority,
                NeoUserThreadFunc aUserFunc);
  virtual OSErr block(CNeoSemaphoreNative *aSemaphore,
                      const long aParam, NeoTime aTime = kNeoForever);
  virtual NeoThreadState getState(void) const {return fState;}
  void resume(void) {
        fState = kNeoThreadReadyState;
        ResumeThread();
  }
  virtual void setState(const NeoThreadState aState,
                        const NeoThreadID aNext = kNeoNoThread);
  virtual void sleep(unsigned long aTime);
  void suspend(void);
  virtual OSErr unblock(CNeoSemaphoreNative *aSemaphore);
  virtual void yield(CNeoThread *aTo = nil);

  static void BeginCriticalSection(void) {}
  static void EndCriticalSection(void) {}
  static void InitThreads(void) {
        ::InitializeCriticalSection(&gNeoCritical);
}
  virtual void Sleep(unsigned long aTime) {sleep(aTime);}
  static void YieldTo(CNeoThread *aTo = nil) {
                GetCurrent()->yield(aTo);
  }
protected:
  NeoThreadState fState;
};


Listing Four
class CNeoThreadPP : public CNeoThread {
public:
  /** Instance Member Functions **/
  CNeoThreadPP(void **aArg, const NeoThreadOptions aOptions,
                const NeoPriority aPriority);
  /** Access Member Functions **/
  virtual OSErr block(CNeoSemaphoreNative *aSemaphore, const long aParam,
                      const NeoTime aTime = kNeoForever);
  virtual NeoThreadState getState(void) const;
  virtual void setState(const NeoThreadState aState,
                        NeoThreadID aNext = kNoThreadID);
  void suspend(void) {Suspend();}
  virtual OSErr unblock(CNeoSemaphoreNative *aSemaphore);
  virtual void yield(CNeoThread *aTo = nil) {
          CNeoThread::Yield(aTo);
  }
  /** Static Member Functions **/
  static void BeginCriticalSection(void) {EnterCritical();}
  static void EndCriticalSection(void) {ExitCritical();}
  static CNeoThreadPP * GetCurrent(void) {
        return (CNeoThreadPP *)GetCurrentThread();
  }
  static void InitThreads(void);
  static void YieldTo(CNeoThread *aTo = nil) {
        CNeoThread::Yield(aTo);
  }
protected:
  /** Macintosh-Specific Member Functions **/
  static void * GetTaskRef(void) {return sThreadTaskRef;}
  static void IOComplete(ParmBlkPtr pbPtr);
  static void AsyncIOResume(CNeoThreadPP *aThread);
  void setIOCompleteProc(NeoThreadBlock *aBlock,
                                         NeoCompletionProc aProc = nil);
  OSErr waitUntilIOCompletes(NeoThreadBlock *aThreadBlock,
  OSErr & volatile aError);
  virtual void setEpilogue(NeoThreadEpilogue aEpilogue, void *aParam);
};


Listing Five
class CMyThread : public CNeoThreadNative {
public:
  CMyThread(void **aArg = nil,
            const NeoThreadOptions aOptions = kCreateIfNeeded,
            const NeoPriority aPriority = kNeoPriorityNormal);
  virtual ~CMyThread(void);
  /** Access Member Functions **/
  virtual long run(void);
};

3


