home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C++ / Applications / Nuntius 1.2 / src / Nuntius / UPeriodic.cp < prev    next >
Encoding:
Text File  |  1994-03-16  |  5.2 KB  |  226 lines  |  [TEXT/MPS ]

  1. // Copyright © 1993 Peter Speck (speck@dat.ruc.dk).  All rights reserved.
  2. // UPeriodic.cp
  3.  
  4. #include "UPeriodic.h"
  5. #include "UThread.h"
  6. #include "UFatalError.h"
  7.  
  8. #include <RsrcGlobals.h>
  9.  
  10. #pragma segment MyTools
  11.  
  12. #define qDebugThreadsPeriodic qDebug & 1
  13.  
  14. class TDoPeriodicActionCommand : public TCommand
  15. {
  16.     public:
  17.         pascal void DoIt();
  18.         
  19.         pascal void Initialize();
  20.         void IDoPeriodicActionCommand(TPeriodicAction *pt);
  21.         pascal void Free();
  22.     private:
  23.         TPeriodicAction *fPeriodicAction;
  24. };
  25.  
  26. pascal void TDoPeriodicActionCommand::Initialize()
  27. {
  28.     inherited::Initialize();
  29.     fPeriodicAction = nil;
  30. }
  31.  
  32. void TDoPeriodicActionCommand::IDoPeriodicActionCommand(TPeriodicAction *pt)
  33. {
  34.     inherited::ICommand(cDoPeriodicActionCommand, nil, false, false, nil);
  35.     fPeriodicAction = pt;
  36. #if qDebugThreadsPeriodic
  37.     fprintf(stderr, "Created TDoPeriodicActionCommand at $%lx\n", long(this));
  38. #endif
  39. }
  40.  
  41. pascal void TDoPeriodicActionCommand::Free()
  42. {
  43. #if qDebugThreadsPeriodic
  44.     fprintf(stderr, "TDoPeriodicActionCommand::Free at $%lx, fPeriodicAction = $%lx\n", long(this), long(fPeriodicAction));
  45. #endif
  46.     fPeriodicAction = nil;
  47.     inherited::Free();
  48. }
  49.  
  50. pascal void TDoPeriodicActionCommand::DoIt()
  51. {
  52. #if qDebugThreadsPeriodic
  53.     fprintf(stderr, "Executing TPeriodicAction at $%lx in thread at $%lx\n", long(fPeriodicAction), long(gCurThread));
  54.     fprintf(stderr, " for service: %s\n", fPeriodicAction->GetDebugDescription());
  55. #endif
  56.     fPeriodicAction->DoPeriodic();
  57. }
  58.  
  59. //----------
  60.  
  61. TPeriodicAction::TPeriodicAction()
  62. {
  63. }
  64.  
  65. pascal void TPeriodicAction::Initialize()
  66. {
  67.     inherited::Initialize();
  68.     fThreadList = nil;
  69.     fLastCheckTick = 0;
  70.     fSleepTicks = 600000;
  71.     fCoHandlerInstalled = false;
  72. }
  73.  
  74. void TPeriodicAction::IPeriodicAction(Boolean useThread)
  75. {
  76.     inherited::IEventHandler(nil);
  77.     FailInfo fi;
  78.     if (fi.Try())
  79.     {
  80. #if qDebugThreadsPeriodic
  81.         fprintf(stderr, "TPeriodicAction created at $%lx (%s)\n", long(this), GetDebugDescription());
  82. #endif
  83.         if (useThread)
  84.             fThreadList = NewThreadList(GetDebugDescription());        
  85.         fi.Success();
  86.     }
  87.     else // fail
  88.     {
  89.         fi.ReSignal();
  90.     }
  91. }    
  92.     
  93. pascal void TPeriodicAction::Free()
  94. {
  95.     if (fCoHandlerInstalled)
  96.         PanicExitToShell("In TPeriodicAction::Free, fCoHandlerInstalled == true");
  97.     if (fThreadList)
  98.     {
  99.         if (fThreadList->fSize)
  100.             PanicExitToShell("In TPeriodicAction::Free, fThreadList->fSize > 0");
  101.         FreeIfObject(fThreadList); fThreadList = nil;
  102.     }
  103. #if qDebugThreadsPeriodic
  104.     fprintf(stderr, "TPeriodicAction at $%lx (%s) free'd\n", long(this), GetDebugDescription());
  105. #endif
  106.     inherited::Free();
  107. }
  108.  
  109. void TPeriodicAction::Close()
  110. {
  111. #if qDebugThreadsPeriodic
  112.     fprintf(stderr, "TPeriodicAction::Close at $%lx (%s)\n", long(this), GetDebugDescription());
  113. #endif
  114.     SetSleep(kMaxLong);
  115. }
  116.  
  117. Boolean TPeriodicAction::IsBusy()
  118. {
  119.     return fThreadList->fSize > 0;
  120. }
  121.  
  122. void TPeriodicAction::SetSleep(unsigned long sleepTicks)
  123. {
  124. #if qDebugThreadsPeriodic
  125.     fprintf(stderr, "TPeriodicAction::SetSleep(%ld) at $%lx (%s)\n", sleepTicks, long(this), GetDebugDescription());
  126. #endif
  127.     fSleepTicks = sleepTicks;
  128.     if (sleepTicks == kMaxLong)
  129.     {
  130.         if (fCoHandlerInstalled)
  131.         {
  132.             gApplication->InstallCohandler(this, false);
  133.             fCoHandlerInstalled = false;
  134.         }
  135.         SetIdleFreq(kMaxLong);
  136.         GoSleep();
  137.         return;
  138.     }
  139.     if (!fCoHandlerInstalled)
  140.     {
  141.         gApplication->InstallCohandler(this, true);
  142.         fCoHandlerInstalled = true;
  143.     }
  144.     SetIdleFreq(sleepTicks);
  145.     if (SkipFirstCheckAfterWakeUp())
  146.         fLastCheckTick = TickCount();
  147.     else
  148.         if (TickCount() - fLastCheckTick >= sleepTicks)
  149.             WakeUp();
  150. }
  151.  
  152. void TPeriodicAction::GoSleep()
  153. {
  154.     fThreadList->KillAll();
  155.     if (fThreadList->fSize)
  156.         PanicExitToShell("In TPeriodicAction::GoSleep, still got threads");
  157.     fLastCheckTick = TickCount();
  158.     fLastIdle = TickCount();
  159. }
  160.  
  161. void TPeriodicAction::WakeUp()
  162. {
  163.     if (fThreadList->fSize == 0 && NeedTime())
  164.     {
  165. #if qDebugThreadsPeriodic
  166.         fprintf(stderr, "TPeriodicAction at $%lx (%s) got nightmare\n", long(this), GetDebugDescription());
  167. #endif
  168.         fLastCheckTick = 0;
  169.         fLastIdle = 0;
  170.         TDoPeriodicActionCommand *cmd = new TDoPeriodicActionCommand();
  171.         cmd->IDoPeriodicActionCommand(this);
  172.         fThreadList->ExecuteCommand(cmd, GetDebugDescription());
  173.     }
  174.     else
  175.     {
  176. #if qDebugThreadsPeriodic
  177.         if (fThreadList->fSize)
  178.             fprintf(stderr, "TPeriodicAction at $%lx (%s) didn't want time\n", long(this), GetDebugDescription());
  179.         else
  180.             fprintf(stderr, "TPeriodicAction at $%lx (%s) is already getting time\n", long(this), GetDebugDescription());
  181. #endif
  182.     }
  183.     fLastCheckTick = TickCount();
  184. }
  185.  
  186. pascal Boolean TPeriodicAction::DoIdle(IdlePhase phase)
  187. {
  188.     if (phase != idleEnd && fThreadList->fSize == 0)
  189.     {
  190.         if (TickCount() - fLastCheckTick >= fSleepTicks * 9 / 8)
  191.         {
  192.             if (NeedTime())
  193.                 WakeUp();
  194.             else
  195.                 fLastCheckTick = TickCount(); // skip this time
  196.         }
  197.     }
  198.     return inherited::DoIdle(phase);
  199. }
  200.  
  201. Boolean TPeriodicAction::NeedTime()
  202. {
  203.     return true;
  204. }
  205.  
  206. Boolean TPeriodicAction::SkipFirstCheckAfterWakeUp()
  207. {
  208.     return false;
  209. }
  210.  
  211. void TPeriodicAction::DoPeriodic()
  212. {
  213. }
  214.  
  215. const char *TPeriodicAction::GetDebugDescription()
  216. {
  217.     return "(unspecified)";
  218. }
  219.  
  220. void TPeriodicAction::DumpDebugDescription()
  221. {
  222.     fprintf(stderr, "  %s at $%lx\n", GetDebugDescription(), long(this));
  223.     fprintf(stderr, "              fCoHandInst = %ld, fSleepTicks = %ld\n", long(fCoHandlerInstalled), fSleepTicks);
  224.     fprintf(stderr, "              fLastCheckTick = %ld, fThreadList->fSize = $%lx\n", fLastCheckTick, fThreadList->fSize);
  225. }
  226.