home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c083 / 20.ddi / CLASSSRC.PAK / THREAD.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-02  |  5.5 KB  |  207 lines

  1. /*------------------------------------------------------------------------*/
  2. /*                                                                        */
  3. /*  THREAD.CPP                                                            */
  4. /*                                                                        */
  5. /*  Copyright (c) 1993 Borland International                              */
  6. /*  All Rights Reserved                                                   */
  7. /*                                                                        */
  8. /*------------------------------------------------------------------------*/
  9.  
  10. #if !defined( __STDLIB_H )
  11. #include <stdlib.h>
  12. #endif  // __STDLIB_H
  13.  
  14. #if !defined( __WINDOWS_H )
  15. #define STRICT
  16. #include <windows.h>
  17. #endif  // __WINDOWS_H
  18.  
  19. #if !defined( __CHECKS_H )
  20. #include <checks.h>
  21. #endif  // __CHECKS_H
  22.  
  23. #if !defined( __CLASSLIB_DEFS_H )
  24. #include "classlib\defs.h"
  25. #endif  // __CLASSLIB_DEFS_H
  26.  
  27. #if !defined( __CLASSLIB_THREAD_H )
  28. #include "classlib\thread.h"
  29. #endif  // __CLASSLIB_THREAD_H
  30.  
  31. DIAG_DEFINE_GROUP(Threads,1,0);
  32.  
  33. HANDLE TThread::Start()
  34. {
  35. #if defined( __MT__ )
  36.     Handle = _beginthreadNT( &TThread::Execute, 0, this, 0, 0, &ThreadId );
  37. #else
  38.     Handle = ::CreateThread( 0, 0, &TThread::Execute, this, 0, &ThreadId );
  39. #endif
  40.     if( Handle != 0 )
  41.         {
  42.         TRACEX( Threads, 1, "Thread started [handle:" << Handle << ']' );
  43.         Stat = Running;
  44.         }        
  45.     else
  46.         {
  47.         TRACEX(Threads, 2, "Thread failed to start" );
  48.         Stat = Invalid;
  49.         throw ThreadError(ThreadError::CreationFailure);
  50.         }
  51.     return Handle;
  52. }
  53.  
  54. DWORD TThread::Suspend()
  55. {
  56.     switch( GetStatus() )
  57.         {
  58.         case Created:
  59.             TRACEX( Threads, 2, "Illegal thread suspension [handle:" << Handle << ']' );
  60.             throw ThreadError(ThreadError::SuspendBeforeRun);
  61.         case Finished:
  62.             TRACEX( Threads, 2, "Illegal thread suspension [handle:" << Handle << ']' );
  63.             throw ThreadError(ThreadError::SuspendAfterExit);
  64.         default:
  65.             TRACEX( Threads, 0, "Thread suspended [handle:" << Handle << ']' );
  66.             Stat = Suspended;
  67.             return ::SuspendThread(Handle);
  68.         }
  69. }
  70.  
  71. DWORD TThread::Resume()
  72. {
  73.     switch( GetStatus() )
  74.         {
  75.         case Created:
  76.             TRACEX( Threads, 2, "Illegal thread resumption [handle:" << Handle << ']' );
  77.             throw ThreadError(ThreadError::ResumeBeforeRun);
  78.         case Running:
  79.             TRACEX( Threads, 2, "Illegal thread resumption [handle:" << Handle << ']' );
  80.             throw ThreadError(ThreadError::ResumeDuringRun);
  81.         case Finished:
  82.             throw ThreadError(ThreadError::ResumeAfterExit);
  83.         default:
  84.             TRACEX( Threads, 0, "Thread resumed [handle:" << Handle << ']' );
  85.             DWORD res = ::ResumeThread(Handle);
  86.             if( res == 0 )
  87.                 Stat = Running;
  88.             return res;
  89.         }        
  90. }
  91.  
  92. void TThread::Terminate()
  93. {
  94.     TRACEX( Threads, 1, "Thread termination requested [handle:" << Handle << ']' );
  95.     TerminationRequested = 1;
  96. }
  97.  
  98. unsigned long TThread::WaitForExit( unsigned long timeout )
  99. {
  100.     TRACEX( Threads, 1, "Waiting for thread exit [handle:" << Handle << ']' );
  101.     if( Stat == Running )
  102.         return ::WaitForSingleObject( Handle, timeout );
  103.     else
  104.         return -1;
  105. }
  106.  
  107. unsigned long TThread::TerminateAndWait( unsigned long timeout )
  108. {
  109.     Terminate();
  110.     return WaitForExit( timeout );
  111. }
  112.  
  113. int TThread::SetPriority( int pri )
  114. {
  115.     TRACEX( Threads, 1, "Thread priority changed to " << pri << " [handle:" << Handle << ']' );
  116.     return ::SetThreadPriority(Handle,pri);
  117. }
  118.  
  119. TThread::ThreadError::ThreadError(ErrorType type) :
  120.     xmsg(MakeString(type)),
  121.     Type(type)
  122. {
  123. }
  124.  
  125. string TThread::ThreadError::MakeString(ErrorType type)
  126. {
  127.     static char *Names[] =
  128.         {
  129.         "Suspend() before Run()",
  130.         "Resume() before Run()",
  131.         "Resume() during Run()",
  132.         "Suspend() after Exit()",
  133.         "Resume() after Exit()",
  134.         "creation failure",
  135.         "destroyed before Exit()",
  136.         "illegal assignment"
  137.         };
  138.     string Msg;
  139.     Msg.reserve(40);
  140.     Msg = "Error[thread]: ";
  141.     Msg += Names[type];
  142.     return Msg;
  143. }
  144.  
  145. TThread::TThread() :
  146.     Handle(0),
  147.     ThreadId(0),
  148.     Stat(Created),
  149.     TerminationRequested(0)
  150. {
  151. }
  152.  
  153. TThread::TThread( const TThread& ) :
  154.     Handle(0),
  155.     ThreadId(0),
  156.     Stat(Created),
  157.     TerminationRequested(0)
  158. {
  159. }
  160.  
  161. TThread::~TThread()
  162. {
  163.     if( GetStatus() != Finished )
  164.         throw ThreadError(ThreadError::DestroyBeforeExit);
  165.     ::CloseHandle(Handle);
  166. }
  167.  
  168. const TThread& TThread::operator = ( const TThread& thread )
  169. {
  170.     switch( GetStatus() )
  171.         {
  172.         case Created:
  173.         case Finished:
  174.             {
  175.             if( this != &thread )
  176.                 {
  177.                 Handle = 0;
  178.                 ThreadId = 0;
  179.                 Stat = Created;
  180.                 TerminationRequested = 0;
  181.                 }
  182.             return *this;
  183.             }
  184.         default:
  185.             throw ThreadError(ThreadError::AssignError);
  186.         }
  187. }
  188.  
  189. unsigned long _stdcall TThread::Execute( void *thread )
  190. {
  191.     return STATIC_CAST(TThread*,thread)->Run();
  192. }
  193.  
  194. //  Call only when Stat claims
  195. //  that the thread is Running.
  196. TThread::Status TThread::CheckStatus() const
  197. {
  198.     DWORD ExitCode;
  199.     ::GetExitCodeThread( Handle, &ExitCode );
  200.     if( ExitCode == STILL_ACTIVE )
  201.         return Running;
  202.     else
  203.         return Finished;
  204. }
  205.  
  206.  
  207.