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