home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1998 / MacHack 1998.toast / Papers / C++ Exceptions / µShell / Core Utilities / Module.cp < prev    next >
Encoding:
Text File  |  1998-06-21  |  5.1 KB  |  277 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        Module.cp
  3.  
  4.     The module class allows us to have independent pieces of code which are initialized 
  5.     automatically at system startup. Unlike the C++ static constructor method, this 
  6.     is guaranteed to happen at a safe time
  7.  
  8. */
  9.  
  10. #include "Module.h"
  11.  
  12. #include "Exceptions.h"
  13.  
  14. #include <Gestalt.h>
  15. #include <CodeFragments.h>
  16.  
  17. DefineClassSingleAbstract(TModule);
  18.  
  19. OTList TModule::gUninitList = {0};    // list of uninitialized modules
  20. OTList TModule::gInitedList = {0};    // list of initialized modules
  21. OTList TModule::gFailedList = {0};    // list of initialized modules
  22.  
  23. #if    FeatureOptional(qThreadManagerSupport)
  24.     bool gHasThreadManager = false;
  25. #endif
  26.  
  27. //static char gModuleListStorage[sizeof(LinkedListOf<TModule>)];
  28.     
  29. #pragma segment Main
  30. //--------------------------------------------------------------------------------
  31. TModule::TModule(bool early)
  32. {
  33.     if (offsetof(TModule, fNextModule) != 8)
  34.     {
  35.         Debugger();
  36.     }
  37.  
  38.     OTLink* link = gUninitList.fHead;
  39.  
  40.     if (early || link == nil)
  41.     {
  42.         fNextModule.fNext = link;
  43.         gUninitList.fHead = &fNextModule;
  44.     }
  45.     else
  46.     {
  47.         OTLink* next = link->fNext;
  48.         
  49.         while (next != nil)
  50.         {
  51.             link = next;
  52.             next = next->fNext;
  53.         }
  54.     
  55.         fNextModule.fNext = nil;
  56.         link->fNext = &fNextModule;
  57.     }
  58. }
  59.  
  60.  
  61. #pragma segment AppCleanup
  62. //--------------------------------------------------------------------------------
  63. TModule::~TModule()
  64. {
  65.     GetUninitList().Remove(*this);
  66.     GetInitedList().Remove(*this);
  67. }
  68.  
  69.  
  70. #pragma segment AppInit
  71. //--------------------------------------------------------------------------------
  72. bool TModule::Validate(void)
  73. {
  74.     return true;
  75. }
  76.  
  77. #pragma segment AppInit
  78. //--------------------------------------------------------------------------------
  79. bool TModule::Available(void)
  80. {
  81.     return true;
  82. }
  83.  
  84.  
  85. #pragma segment AppInit
  86. //--------------------------------------------------------------------------------
  87. bool TModule::Initialized(void)
  88. {
  89.     return true;
  90. }
  91.  
  92.  
  93. #pragma segment AppInit
  94. //--------------------------------------------------------------------------------
  95. // Determine if we have tried to initialize this module (successful or not)
  96. // by default, we scan back through the lined list from gInitModule, but 
  97. // subclasses which cache wether they have been initialized may want to override
  98. // this method for speed
  99. bool TModule::InitializeCalled(void)
  100. {
  101.     return !GetUninitList().IsInList(this);
  102. }
  103.  
  104.  
  105. #pragma segment AppInit
  106. //--------------------------------------------------------------------------------
  107. // This routine may be called from within a manager's Initialize method to
  108. // force another package to be initialized first returning 
  109. bool TModule::InitializeAfter(TModule& mod)
  110. {
  111.     Assert(&mod != nil);
  112.  
  113.     if (GetUninitList().Remove(mod))
  114.     {
  115.         try
  116.         {
  117.             // module wasn't initialized
  118.             
  119.             InitializeObject(&mod);    // Initialize it
  120.         
  121.             // ••• handle failure
  122.             
  123.             GetInitedList().AddFirst(&mod);
  124.         }
  125.         catch(...)
  126.         {
  127.             GetFailedList().AddFirst(&mod);
  128.         
  129.             throw;
  130.         }
  131.     }
  132.     
  133.     return true;
  134. }
  135.  
  136. bool TModule::IsRequired()
  137. {
  138.     return true;
  139. }
  140.  
  141. bool TModule::InitializeWhenUsed()
  142. {
  143.     return false;
  144. }
  145.  
  146.  
  147. #pragma segment AppInit
  148. //--------------------------------------------------------------------------------
  149. // This function is used to initialize all of the managers after the system 
  150. // is up and running
  151.  
  152. /*
  153. bool TModule::ValidateSystem(void)
  154. {
  155.     EmbeddedLinkPtr(TModule, fNextModule) link = GetUninitList().GetFirst();
  156.     
  157.     bool valid = true;
  158.     
  159.     while (link)
  160.     {
  161.         valid = false;
  162.     
  163.         try
  164.         {
  165.             valid = link->Validate();
  166.         }
  167.         catch(...)
  168.         {
  169.         }
  170.         
  171.         if (!valid)
  172.         {
  173.             if (GetUninitList().Remove(link))
  174.             {
  175.                 GetFailedList().AddFirst(link);
  176.             }
  177.         }
  178.         
  179.         link = link.Next();
  180.     }
  181.     
  182.     return valid;
  183. }
  184. */
  185.  
  186. #pragma segment AppInit
  187. //--------------------------------------------------------------------------------
  188. // This function is used to initialize all of the managers after the system 
  189. // is up and running
  190. bool TModule::InitializeModules(void)
  191. {
  192.     EmbeddedLinkPtr(TModule, fNextModule) mod = GetUninitList().GetFirst();
  193.     
  194.     bool valid = true;
  195.     
  196.     while (mod)
  197.     {
  198.         valid = false;
  199.     
  200.         try
  201.         {
  202.             valid = mod->Validate();
  203.         }
  204.         catch(...)
  205.         {
  206.         }
  207.         
  208.         if (!valid)
  209.         {
  210.             if (GetUninitList().Remove(mod))
  211.             {
  212.                 GetFailedList().AddFirst(mod);
  213.             }
  214.             
  215.             if (!mod->IsRequired())
  216.             {
  217.                 valid = true;
  218.             }
  219.         }
  220.         
  221.         mod = mod.Next();
  222.     }
  223.     
  224.     if (valid)
  225.     {
  226.         try
  227.         {
  228.             while (mod = GetUninitList().RemoveFirst())
  229.             {
  230.                 InitializeObject(mod);
  231.                 
  232.                 GetInitedList().AddFirst(mod);
  233.             }
  234.             
  235.             return true;
  236.         }
  237.         catch(...)
  238.         {
  239.             FinalizeModules();
  240.  
  241.             return false;
  242.         }
  243.     }
  244.  
  245.     return valid;
  246. }
  247.  
  248.  
  249. #pragma segment AppCleanup
  250. //--------------------------------------------------------------------------------
  251. // Tear down any modules which have beem initialized
  252. void TModule::FinalizeModules(void)
  253. {
  254.     TModule* module;
  255.     
  256.     while ((module = GetInitedList().RemoveFirst()) != nil)
  257.     {
  258.         try
  259.         {
  260.             FinalizeObject(module);
  261.         }
  262.         catch(...)
  263.         {
  264.         #if qDebug
  265.             SysBreakStr("\pFailure in CleanupModules()");
  266.         #endif
  267.         }
  268.  
  269.         GetUninitList().AddFirst(*module);
  270.     }
  271. }
  272.  
  273. /*
  274. this isi a test for the next sixty seconds the broadcasters in your area
  275. in cooperation with the FCC and other authorities, will conduct a test of
  276. the emergency broadcast network. This is only a test.
  277. */