Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

237 lines
5.7 KiB

  1. /*
  2. *
  3. * NOTES:
  4. *
  5. * REVISIONS:
  6. * ane09DEC92 - added code for rundown of threads
  7. * ane30Dec92 - increase stack size for threads
  8. * jod02Feb93 - increase stack size for threads to 10240
  9. * ane08Feb93 - added ExitWait
  10. * pcy05Mar93 - split off from thread.cxx
  11. * rct20Apr93 - changed ExitNow(), added appropriate header files
  12. * pcy28Apr93 - Removed debug puts() left in code
  13. * cad27May93 - fixed semaphore handling to let thread exit
  14. * tje01Jun93 - Added use of NullSemaphore for single-threaded platforms
  15. * cad09Jul93: using new semaphores
  16. * cad15Jul93: releasing during exitwait to avoid deadlocks
  17. * cad07Oct93: Moved timeout constant to .h file
  18. * cad27Oct93: Fixed problem with global possibly being gone on exitwait()
  19. * rct16Nov93: Added single thread implementation
  20. * ajr24Nov93: Added SetLastPeriod. Took method out of header file.
  21. * ajr24Nov93: Initialized theLastPeriod in constructor
  22. * cad11Jan94: Changes for new process manager
  23. * jps28aug94: added test of theExitSem in ExitNow()
  24. * ajr02May95: Need to stop carrying time in milliseconds
  25. * srt24Oct96: Fixed time_out value usage
  26. */
  27. #include "cdefine.h"
  28. extern "C" {
  29. #if(C_OS & C_OS2)
  30. #define INCL_BASE
  31. #define INCL_NOPM
  32. #define UINT UINT_os2
  33. #define ULONG ULONG_os2
  34. #define COLOR COLOR_os2
  35. #include "os2.h"
  36. #undef UINT
  37. #undef ULONG
  38. #undef COLOR
  39. #endif
  40. #ifdef SINGLETHREADED
  41. #include <time.h>
  42. #endif
  43. }
  44. #include "thrdable.h"
  45. #if (C_OS & C_OS2)
  46. #include "apcsem2x.h"
  47. #elif (C_OS & C_NLM)
  48. #include "nlmsem.h"
  49. #elif (C_OS & C_NT)
  50. #include "apcsemnt.h"
  51. #include "mutexnt.h"
  52. #endif
  53. #ifdef SINGLETHREADED
  54. #include "nullsem.h"
  55. #include "procmgr.h"
  56. #endif
  57. //#include "timerman.h"
  58. //-------------------------------------------------------------------
  59. Threadable::Threadable ()
  60. {
  61. SetThreadName("Unknown");
  62. #ifdef MULTITHREADED
  63. theResumeFlag = new ApcSemaphore();
  64. theExitSem = new ApcSemaphore();
  65. theExitDoneSem = new ApcSemaphore();
  66. #else
  67. theResumeFlag = new NullSemaphore();
  68. theExitSem = new NullSemaphore();
  69. theExitDoneSem = new NullSemaphore();
  70. theServicePeriod = DEFAULT_SERVICE_PERIOD;
  71. theLastPeriod = 0;
  72. theNextPeriod = 0;
  73. #endif
  74. }
  75. //-------------------------------------------------------------------
  76. Threadable::~Threadable ()
  77. {
  78. #if (C_OS & C_NT)
  79. //
  80. // Dont remove this wait. NT needs it for some reason??
  81. Sleep(0);
  82. #endif
  83. delete theResumeFlag;
  84. theResumeFlag = (PSemaphore)NULL;
  85. delete theExitSem;
  86. theExitSem = (PSemaphore)NULL;
  87. delete theExitDoneSem;
  88. theExitDoneSem = (PSemaphore)NULL;
  89. }
  90. //-------------------------------------------------------------------
  91. // This function is used to tell a threadable object to exit - it will
  92. // pause for THREAD_EXIT_TIMEOUT milliseconds for the thread to exit and
  93. // then will continue
  94. INT Threadable::Exit()
  95. {
  96. #ifdef SINGLETHREADED
  97. return _theProcessManager->RemoveThread(this);
  98. #else
  99. theResumeFlag->Pulse(); // just in case
  100. theExitSem->Post();
  101. return theExitDoneSem->TimedWait((THREAD_EXIT_TIMEOUT*1000));
  102. #endif
  103. }
  104. VOID Threadable::SetThreadName(PCHAR aName)
  105. {
  106. strncpy(theThreadName, aName, MAX_THREAD_NAME);
  107. }
  108. PCHAR Threadable::GetThreadName(VOID)
  109. {
  110. return theThreadName;
  111. }
  112. //-------------------------------------------------------------------
  113. // This function is used to tell a threadable object to exit - it will
  114. // wait indefinitely for the thread to exit
  115. INT Threadable::ExitWait()
  116. {
  117. #ifdef SINGLETHREADED
  118. return _theProcessManager->RemoveThread(this);
  119. #else
  120. theExitSem->Post(); // tell them to go away
  121. theResumeFlag->Post(); // just in case
  122. return theExitDoneSem->Wait(); // wait for them to do so
  123. #endif
  124. }
  125. //-------------------------------------------------------------------
  126. INT Threadable::Reset()
  127. {
  128. if (theExitSem->IsPosted())
  129. {
  130. theExitSem->Clear();
  131. }
  132. if (theResumeFlag->IsPosted())
  133. {
  134. theResumeFlag->Clear();
  135. }
  136. if (theExitDoneSem->IsPosted())
  137. {
  138. theExitDoneSem->Clear();
  139. }
  140. return ErrNO_ERROR;
  141. }
  142. //-------------------------------------------------------------------
  143. // This function is called from within a thread to see if Exit or ExitWait
  144. // has been called.
  145. INT Threadable::ExitNow()
  146. {
  147. #ifdef MULTITHREADED
  148. if (theExitSem)
  149. return (theExitSem->IsPosted());
  150. else
  151. return TRUE;
  152. #else
  153. return ErrNO_ERROR;
  154. #endif
  155. }
  156. //-------------------------------------------------------------------
  157. // This function is called from within a thread to mark the fact that the
  158. // thread has been exited.
  159. INT Threadable::DoneExiting()
  160. {
  161. INT err = ErrNO_ERROR;
  162. if (this != NULL && theExitDoneSem != NULL) {
  163. theExitDoneSem->Post();
  164. }
  165. return err;
  166. }
  167. //-------------------------------------------------------------------
  168. #ifdef SINGLETHREADED
  169. ULONG Threadable::GetServicePeriod() const
  170. {
  171. return theServicePeriod;
  172. }
  173. VOID Threadable::SetServicePeriod(ULONG period)
  174. {
  175. theServicePeriod = period;
  176. ULONG next_period = 0L;
  177. if (theLastPeriod > 0) {
  178. next_period = theLastPeriod + theServicePeriod;
  179. }
  180. _theProcessManager->SetNextServiceTime(this, next_period);
  181. }
  182. ULONG Threadable::GetLastPeriod(void)
  183. {
  184. return theLastPeriod;
  185. }
  186. VOID Threadable::SetLastPeriod(ULONG period)
  187. {
  188. theLastPeriod = period;
  189. }
  190. ULONG Threadable::GetNextPeriod(void)
  191. {
  192. return theNextPeriod;
  193. }
  194. VOID Threadable::SetNextPeriod(ULONG period)
  195. {
  196. theNextPeriod = period;
  197. _theProcessManager->SetNextServiceTime(this, theNextPeriod);
  198. }
  199. #endif