home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 February: Tool Chest / Apple Developer CD Series Tool Chest February 1996 (Apple Computer)(1996).iso / Sample Code / AOCE Sample Code / PowerTalk Access Modules / Sample PMSAM / PMSAM Framework / RoboSamSlot / TThread.h < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-28  |  7.6 KB  |  290 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        TThread.h
  3.  
  4.     Contains:    xxx put contents here xxx
  5.  
  6.     Written by:    Tim Harnett
  7.  
  8.     Copyright:    © 1994 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.         <18>     2/17/95    TMH        fixed a oops re16 got nuked
  13.         <15>      2/7/95    TMH        added userinterrupt stuff
  14.         <14>      2/6/95    TMH        redid CEventQueue using CLinkedList
  15.         <12>    12/20/94    TMH        fix bug so we don't overflow event queue
  16.         <11>    12/12/94    TMH        added of thread events
  17.         <10>    11/17/94    TMH        increased wakeupthread stack size
  18.          <9>    11/11/94    TMH        fixed TWakeupThread::Busy() to look at IO state
  19.          <8>    11/10/94    TMH        use StopForIO
  20.          <7>     11/8/94    TMH        added fIdentifierTag
  21.          <6>    10/28/94    TMH        added gAppTaskRef and StartThreadFromCompletionRoutine
  22.          <5>    10/26/94    TMH        added GetThreadA5
  23.          <4>    10/25/94    TMH        added TWakeupThread
  24.          <3>    10/11/94    TMH        added StopThread, StartThread
  25.          <2>     10/6/94    TMH        added TApplicationThread
  26.          <1>     9/21/94    TMH        seperated from Application.cp
  27.                  9/21/94    TMH        xxx put comment here xxx
  28.  
  29.     To Do:
  30. */
  31.  
  32.  
  33. #ifndef __TThread__
  34. #define __TThread__
  35.  
  36. #ifndef __THREADS__
  37. #include "Threads.h"
  38. #endif
  39.  
  40. #ifndef __Debug__
  41. #include "Debug.h"
  42. #endif
  43.  
  44. #ifndef __CLinkedList__
  45. #include "CLinkedList.h"
  46. #endif
  47.  
  48.  
  49. class CThreadEventQueue;
  50. class CThreadEvent;
  51. class TCooperativeThread;
  52.  
  53. const Boolean kAllowDuplicateEvent     = true;
  54. const Boolean kDontAllowDuplicateEvent = false;
  55.  
  56.  
  57. //---------------------------------------
  58. //        C T h r e a d E v e n t Q u e u e
  59. //----------------------------------------
  60.  
  61. class CThreadEvent : public CLink {
  62. public:
  63.             CThreadEvent() {
  64.                 fEventID = 0;
  65.                 fEventData0 = 0;
  66.                 fEventData1 = 0;
  67.                 fEventData2 = 0;
  68.             };
  69.  
  70.             CThreadEvent(OSType eventID,long eventData0=0,long eventData1=0,long eventData2=0) 
  71.             {
  72.                 fEventID = eventID;
  73.                 fEventData0 = eventData0;
  74.                 fEventData1 = eventData1;
  75.                 fEventData2 = eventData2;
  76.             };
  77.             
  78.     long    fEventID;
  79.     long    fEventData0;
  80.     long    fEventData1;
  81.     long    fEventData2;
  82.     
  83.     long    EventID()  { return fEventID; };
  84.     long    EventData0() { return fEventData0; };
  85.     long    EventData1() { return fEventData1; };
  86.     long    EventData2() { return fEventData2; };
  87.     
  88. };
  89.  
  90. //---------------------------------------
  91. //        C T h r e a d E v e n t Q u e u e
  92. //----------------------------------------
  93.  
  94. #define kMaxThreadEvents    16
  95.  
  96.  
  97. class CThreadEventQueue {
  98.     friend    class CThreadEventIterator;
  99.     friend    class TCooperativeThread;
  100.  
  101. public:
  102.                     CThreadEventQueue();
  103.                 
  104.     void            Insert(CThreadEvent& threadEvent);
  105.     void            Remove(CThreadEvent& threadEvent);
  106.     void            FlushEvents(long eventID);
  107.     long             EventCount() {    return fEvents.Count(); }
  108.     
  109. private:
  110.     void            CopyNextEvent(CThreadEvent& threadEvent);
  111.     
  112.     CLinkedList        fEvents;
  113.     
  114.     CLinkedList        fAvail;
  115.     
  116.     CThreadEvent    fEventBufs[kMaxThreadEvents];        // this is how we allocate event buffers.
  117. };
  118.  
  119.  
  120.  
  121.  
  122. //-----------------------------------------------
  123. //        T C o o p e r a t i v e T h r e a d
  124. //-----------------------------------------------
  125.  
  126. //    This is abstract base class.  You have to subclass it to get 
  127. //    a thread.
  128.  
  129. #define kDefaultThreadStackSize 6000
  130. #define kNoCreationOptions 0
  131.  
  132. //    Additional options we define -- we use the upper bits of ThreadOptions
  133. #define kNeedEventQueue (1<<31)
  134.  
  135.  
  136. enum ThreadIOState {
  137.     sThreadIOIdle = 100,            // we want these number to not conflict with Threads.h definitions.
  138.     sThreadStoppedForIO
  139. };
  140.  
  141.  
  142. class TCooperativeThread {
  143.     friend    class CThreadEventIterator;
  144. public:
  145.         TCooperativeThread();
  146.         ~TCooperativeThread();
  147.     void ICooperativeThread(OSType tag, Size stackSize=kDefaultThreadStackSize,ThreadOptions createOptions=kNoCreationOptions,long wneSleep=10);
  148.  
  149.     virtual void*         ThreadMain() = 0;        // you have to define this.
  150.     static pascal void* __ThreadMain(void* inParam);
  151.  
  152.     long        GetWNESleep() { return fWNESleep; };
  153.     
  154.     //-------------------
  155.     //    State Management
  156.     //-------------------
  157.     
  158.     
  159.             ThreadState    GetThreadState();
  160.             OSErr        StartThread() { return(SetThreadState(fThreadID, kReadyThreadState, kApplicationThreadID)); }
  161.             void        StartThreadFromCompletionRoutine() { ::SetThreadReadyGivenTaskRef(gAppTaskRef,fThreadID); };
  162.             OSErr        StopThread() { return(SetThreadState(fThreadID, kStoppedThreadState, kApplicationThreadID)); }
  163.             void        StopForIO();
  164.  
  165.             Boolean        IsStopped() { return this->GetThreadState() == kStoppedThreadState; };
  166.             
  167.     //-------------------
  168.     //    Task switching
  169.     //------------------
  170.     
  171.     
  172.     static pascal void         SwitchInProc ( ThreadID threadBeingSwitched, void* switchProcParam );
  173.     static pascal void         SwitchOutProc ( ThreadID threadBeingSwitched, void* switchProcParam );
  174.                   void        Yield(TCooperativeThread* threadToRun=0);
  175.                   
  176.  
  177.     //-------------------
  178.     //    Event Queue
  179.     //-------------------
  180.  
  181.  
  182.             OSErr        QueueEvent(CThreadEvent& threadEvent);
  183.             OSErr        PostEvent(long eventID, long eventData=0, Boolean allowDuplicate=kAllowDuplicateEvent);
  184.             OSErr         PostEvent(CThreadEvent& theEvent, Boolean allowDuplicate=kAllowDuplicateEvent);
  185.             
  186.             void        FlushEvents(long eventID) { fEventQueue->FlushEvents(eventID); };
  187.     CThreadEvent*        WaitNextEvent();
  188.     CThreadEvent*        GetNextEvent();
  189.     CThreadEvent*        EventAvail();
  190.  
  191.     OSType                UserInterrupt() { return fUserInterrupt; };
  192.     Boolean                HasUserInterrupted() { return fUserInterrupt != 0; };
  193.     void                SetUserInterrupt(OSType interruptID) { ASSERT(fUserInterrupt==0); fUserInterrupt = interruptID; }
  194.     void                ClearUserInterrupt() { fUserInterrupt = 0; }
  195.     
  196.  
  197.  
  198.     //-------------------
  199.     //    Accessors
  200.     //------------------
  201.     
  202.     long    GetThreadA5() { return fA5; };
  203.  
  204. protected:
  205.     long            fWNESleep;
  206.     ThreadID        fThreadID;
  207.     OSType            fIdentifierTag;                    //    so we can see what thread is which in the debugger
  208.     
  209.     ThreadIOState    fThreadIOState;
  210.     void*            fOutParam;
  211.  
  212.     OSType            fUserInterrupt;
  213.     
  214.     void*            fSavedTopHandler;
  215.     long            fA5;
  216.     
  217.     static ThreadTaskRef    gAppTaskRef;            //    this is the same for all threads,  set by TApplicationThread.
  218.     
  219.     static    unsigned long            gDebugCallCount;        // this is for debugging, remove it later
  220.  
  221.     CThreadEventQueue*    fEventQueue;
  222.     CLinkedList*        EventList() { return &fEventQueue->fEvents; }
  223.     
  224. };
  225.  
  226.  
  227. //-----------------------------------------
  228. //    C T h r e a d E v e n t I t e r a t o r
  229. //------------------------------------------
  230.  
  231.  
  232. class CThreadEventIterator : public CLinkedListIterator {
  233. public:
  234.                         CThreadEventIterator(CThreadEventQueue* eventQueue) : CLinkedListIterator( &eventQueue->fEvents ) {}
  235.                         CThreadEventIterator(TCooperativeThread* thread) : CLinkedListIterator( thread->EventList() ) {}
  236.     CThreadEvent*         FirstEvent() { return (CThreadEvent*) CLinkedListIterator::FirstItem(); }
  237.     CThreadEvent*          NextEvent() { return (CThreadEvent*) CLinkedListIterator::NextItem(); };
  238.         void            FlushCurrentEvent() {  CLinkedListIterator::UnlinkCurrentItem(); }
  239. };
  240.  
  241.  
  242. //-----------------------------------------------
  243. //        T A p p l i c a t i o n T h r e a d
  244. //-----------------------------------------------
  245.  
  246.  
  247. //    The Application thread is "special" it is automatically created by the
  248. //    Thread Manager.  We however need a Thread object so we can do neat stuff
  249.  
  250.  
  251. class  TApplicationThread : public TCooperativeThread {
  252. public:
  253.                 TApplicationThread() {};
  254.  
  255.     void        IApplicationThread();
  256.     virtual void*         ThreadMain();        // Override. Hit Wall. Never Called!
  257.     
  258. };
  259.  
  260.  
  261.  
  262.  
  263. //---------------------------------
  264. //    T W a k e u p T h r e a d 
  265. //    Thread used for ASynchronous IO
  266. //    See develop Issue 17.
  267. //---------------------------------
  268.  
  269. #define    kWakeupThreadStacksize    6000
  270.  
  271. class TWakeupThread : public TCooperativeThread {
  272. public:
  273.                         TWakeupThread();
  274.             void        IWakeupThread();
  275.     virtual void*         ThreadMain();
  276.  
  277.             void        SetThreadToWake(TCooperativeThread* threadToWake) { fThreadToWake = threadToWake; };
  278.             Boolean        Busy() { return fThreadToWake != 0 ? fThreadToWake->GetThreadState() == sThreadStoppedForIO : false; };
  279. private:
  280.     TCooperativeThread*    fThreadToWake;
  281.  
  282. };
  283.  
  284.  
  285.  
  286.  
  287.  
  288.  
  289.  
  290. #endif __TThread__