home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / BC_502 / MTHREAD.PAK / DEMOBASE.H < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-06  |  3.2 KB  |  106 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows
  3. // Copyright (c) 1991, 1995 by Borland International, All Rights Reserved
  4. //
  5. // Base window classes for the multi-thread GDI demo windows
  6. //----------------------------------------------------------------------------
  7. #if !defined(DEMOBASE_H)
  8. #define DEMOBASE_H
  9.  
  10. #include <owl/mdichild.h>
  11. #include <classlib/thread.h>
  12.  
  13. #define max(a,b)    (((a) > (b)) ? (a) : (b))
  14. #define min(a,b)    (((a) < (b)) ? (a) : (b))
  15.  
  16. //
  17. // class TWorkerThread
  18. // ~~~~~ ~~~~~~~~~~~~~
  19. // Provides the fundamental control mechanism for running worker threads
  20. // and synchronizing them with OWL applications. It uses TThread for its basic
  21. // thread management, but uses a different mechanism for terminating threads,
  22. // going through an event semaphore rather than a simple flag. This is needed
  23. // so that the worker thread can check both the event semaphore and OWL's
  24. // internal message queue synchronization semaphore.
  25. // 
  26. // The worker thread should call Sync() which will block until the OWL
  27. // synchronization semaphore is available or until the event semaphore is
  28. // triggered. If the thread was unblocked by the event semaphore Sync()
  29. // returns a non-zero value, and the thread should exit. If the thread was
  30. // unblocked by the synchronization semaphore the thread owns a lock on that
  31. // semaphore.
  32. //
  33. class TWorkerThread : public TThread
  34. {
  35.   public:
  36.     TWorkerThread();
  37.  
  38.     void Terminate();
  39.     ulong TerminateAndWait(ulong timeout = NoLimit);
  40.  
  41.   protected:
  42.     TEventSemaphore Done;  // Event that signals this thread to exit
  43. };
  44.  
  45. //----------------------------------------------------------------------------
  46.  
  47. //
  48. inline TWorkerThread::TWorkerThread()
  49. :
  50.   Done(false, false)  //Done event:  not manual-reset, not initally triggered
  51. {
  52. }
  53.  
  54. //
  55. // Terminate this thread by settting its done event to signal it to exit
  56. //
  57. inline void TWorkerThread::Terminate()
  58. {
  59.   Done.Set();
  60. }
  61.  
  62. //
  63. // Need to override this non-virtual to use our Terminate()
  64. //
  65. inline ulong TWorkerThread::TerminateAndWait(ulong timeout)
  66. {
  67.   Terminate();
  68.   return WaitForExit(timeout);
  69. }
  70.  
  71. //----------------------------------------------------------------------------
  72.  
  73. //
  74. // class TBaseDemoWindow
  75. // ~~~~~ ~~~~~~~~~~~~~~~
  76. // has been modified from the version in the GDIDEMO example. It now has
  77. // TWorkerThread as a base class. It overrides TWorkerThread::Run() (which is
  78. // pure virtual and inherited from TThread) to implement a worker loop which
  79. // calls TBaseDemoWindow::ClockTick() periodically. Derived classes should
  80. // override ClockTick() to perform their data acquisition and logging.
  81. //
  82. // In this case, the modifications to the GDIDEMO example are trivial:
  83. // The constructor for the derived class should call Start() after the object
  84. // has been fully constructed.
  85. //
  86. class TBaseDemoWindow : public TWindow, private TWorkerThread {
  87.   public:
  88.     TBaseDemoWindow();
  89.  
  90.     virtual TApplication* GetApplication() const;
  91.  
  92.     bool CanClose();
  93.  
  94.     TThread::THandle Start();
  95.  
  96.   private:
  97.     int Run();
  98.     virtual void ClockTick() = 0;
  99.  
  100.     TSemaphoreSet Sync;  // Set of semaphore objects to sync this with app
  101.  
  102.   DECLARE_CASTABLE;
  103. };
  104.  
  105. #endif
  106.