home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Snippets / Threads Interface / CMainThread.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-04-03  |  4.6 KB  |  211 lines  |  [TEXT/KAHL]

  1. /***
  2.  * CMainThread.c
  3.  *
  4.  *  Method to implement the main thread.
  5.  *        Copyright © Gordon Watts 1994 (gwatts@fnal.fnal.gov)
  6.  *
  7.  ***/
  8.  
  9. #include "CMainThread.h"
  10. #include "CErrorRecorder.h"
  11. #include <Exceptions.h>
  12. #include "util.h"
  13.  
  14. extern FailInfo        *gTopHandler;
  15. extern char            gDefaultPropagation;
  16.  
  17. /**
  18.  * CMainThread
  19.  *
  20.  *  Init.  We must be created in the main thread.  If we are not, then we aren't
  21.  *  going to work properly!
  22.  *
  23.  **/
  24. CMainThread :: CMainThread (void)
  25. {
  26.     HLock (this);
  27.     FailOSErr(GetCurrentThread (&theThread));
  28.     HUnlock (this);
  29.     AssertStr (theThread != kNoThreadID, "\pBad Thread Id!");
  30.  
  31.     theSInfo = (switcherInfo *) NewPtrClear (sizeof (switcherInfo));
  32.     FailMemError ();
  33.     AssertStr (theSInfo, "\pHey -- bad bad nil pointer but no mem error!");
  34. }
  35.  
  36. /**
  37.  * ~CMainThread
  38.  *
  39.  *  Close up shop
  40.  *
  41.  **/
  42. CMainThread :: ~CMainThread (void)
  43. {
  44.     theThread = kNoThreadID;
  45.  
  46.     DisposPtr (theSInfo);
  47.     FailMemError ();
  48.     theSInfo = 0;
  49. }
  50.  
  51.  
  52. /**
  53.  * isRunning
  54.  *
  55.  *  Return true if this thread is up and going
  56.  *
  57.  **/
  58. Boolean CMainThread :: isRunning (void)
  59. {
  60.     return (theThread != kNoThreadID);
  61. }
  62.  
  63. /**
  64.  * Start
  65.  *
  66.  *  We don't actually start the thread (this puppy is already running) but we do
  67.  *  setup the correct catch/fail handlers...
  68.  *
  69.  **/
  70. void CMainThread :: Start (void)
  71. {
  72.     SetupThreadSwitcher (TRUE);
  73. }
  74.  
  75. /**
  76.  * Stop
  77.  *
  78.  *  Tear down the thread switcher.  We don't really stop the thread because this
  79.  *  is the main thread.
  80.  *
  81.  **/
  82. void CMainThread :: Kill (void)
  83. {
  84.     KillThreadSwitcher ();
  85. }
  86.  
  87. /**
  88.  * SetupThreadSwitcher
  89.  *
  90.  *  Setup the thread switcher routine.  If the argument is false, us the orignal
  91.  *  settings of everything we know about.  Otherwise, just use the current values cnd
  92.  *  take them as correct (tjis is so a regular thread won't be using the application's
  93.  *  failure handler when it dies -- might not even exist any longer!).
  94.  *
  95.  **/
  96. void CMainThread :: SetupThreadSwitcher (Boolean useCurrentValues)
  97. {
  98.     AssertStr (theThread != kNoThreadID, "\pNo thread up and running yet!");
  99.     AssertStr (theSInfo, "\pNo space allocated for storage block!");
  100.  
  101.     /**
  102.      ** Init the block of values that we are going to use to pass to the thread
  103.      ** switcher routine.
  104.      **/
  105.  
  106.     theSInfo->theAppA5 = SetCurrentA5 ();
  107.     theSInfo->threadObj = this;
  108.  
  109.     /**
  110.      ** Save the current values of the exceptions stuff
  111.      **/
  112.  
  113.     if (useCurrentValues) {
  114.         savedLastError = gLastError;
  115.         savedLastMessage = gLastMessage;
  116.         savedDefaultPropagation = gDefaultPropagation;
  117.         savedTopHandler = gTopHandler;
  118.     } else {
  119.         savedLastError = 0;
  120.         savedLastMessage = 0;
  121.         savedTopHandler = 0L;
  122.         savedDefaultPropagation = TRUE;
  123.     }
  124.  
  125.     FailOSErr (SetThreadSwitcher (theThread, &switcherCallBackIn, theSInfo, true));
  126.     FailOSErr (SetThreadSwitcher (theThread, &switcherCallBackOut, theSInfo, false));
  127. }
  128.  
  129. /**
  130.  * KillThreadSwitcher
  131.  *
  132.  *  Turn off the thread switcher now -- don't need it any longer...
  133.  *
  134.  **/
  135. void CMainThread :: KillThreadSwitcher (void)
  136. {
  137.     FailOSErr (SetThreadSwitcher (theThread, 0L, 0L, true));
  138.     FailOSErr (SetThreadSwitcher (theThread, 0L, 0L, false));
  139. }
  140.  
  141. /**
  142.  * switcherCallBack
  143.  *
  144.  *  Routine that is called back with the switcher info -- we call the object routine
  145.  *  to do the actual work (after setting up the A5 world, of course)
  146.  *
  147.  **/
  148. static pascal void CMainThread :: switcherCallBackIn (ThreadID threadSwitching, void *ptr)
  149. {
  150.     switcherInfo     *theInfo = (switcherInfo *) ptr;
  151.     long            oldA5;
  152.  
  153.     oldA5 = SetA5 (theInfo -> theAppA5);
  154.     
  155.     if (theInfo -> threadObj == 0) {
  156.         CErrorRecorder :: gError -> IMessage ("\pBad thread object in switch in routine");
  157.     } else {
  158.         (theInfo -> threadObj) -> DoSwitchIn ();
  159.     }
  160.     SetA5 (oldA5);
  161. }
  162.  
  163. /**
  164.  * swktcherCallBackOut
  165.  *
  166.  *  Called during interupt time when we are attempting to swtich out a thread.
  167.  *  Setup the a5 world, and call a real thread method to do the work
  168.  *
  169.  **/
  170. static pascal void CMainThread :: switcherCallBackOut (ThreadID theThread, void *ptr)
  171. {
  172.     switcherInfo    *theInfo = (switcherInfo *) ptr;
  173.     long            oldA5;
  174.     
  175.     oldA5 = SetA5 (theInfo -> theAppA5);
  176.     if (theInfo -> threadObj == 0) {
  177.         CErrorRecorder :: gError -> IMessage ("\pBad thread object in switch out routine");
  178.     } else {
  179.         (theInfo -> threadObj) -> DoSwitchOut ();
  180.     }
  181.     SetA5 (oldA5);
  182. }
  183.  
  184. /**
  185.  * DoSwitchIn
  186.  *
  187.  *  Ok, this thread is on its way in, better set up everything!
  188.  *
  189.  **/
  190. void CMainThread :: DoSwitchIn (void)
  191. {
  192.     gLastError = savedLastError;
  193.     gLastMessage = savedLastMessage;
  194.     gTopHandler = savedTopHandler;
  195.     gDefaultPropagation = savedDefaultPropagation;
  196. }
  197.  
  198. /**
  199.  * DoSwktchOut
  200.  *
  201.  *  Thread is on its way out -- save our stuff!
  202.  *
  203.  **/
  204. void CMainThread :: DoSwitchOut (void)
  205. {
  206.     savedLastError = gLastError;
  207.     savedLastMessage = gLastMessage;
  208.     savedTopHandler = gTopHandler;
  209.     savedDefaultPropagation = gDefaultPropagation;
  210. }
  211.