Win32Condition.h
上传用户:chinafayin
上传日期:2022-04-05
资源大小:153k
文件大小:3k
源码类别:

并行计算

开发平台:

Visual C++

  1. #ifndef _WIN32VODITIONPRODUCER_CONDITION
  2. #define PRODUCER_CONDITION
  3. #ifdef WIN32
  4. #include "Mutex.h"
  5. namespace OpenThreads {
  6. class Win32ConditionImpl
  7. {
  8. public:
  9. /// number of waiters.
  10. long waiters_;
  11. Condition(long max = 0L)
  12. {
  13. waiters_ = 0;
  14. sema_ = CreateSemaphore(NULL,0,0x7fffffff,NULL);
  15. waiters_done_ = CreateEvent(NULL,FALSE,FALSE,NULL);
  16. }
  17. ~Condition()
  18. {
  19. // CloseHandle(sema_);
  20. // CloseHandle(waiters_done_);
  21. }
  22. inline int broadcast ()
  23. {
  24.  waiters_lock_.lock();
  25.  int have_waiters = 0;
  26. if (waiters_ > 0)
  27. {
  28.       // We are broadcasting, even if there is just one waiter...
  29.   // Record the fact that we are broadcasting.  This helps the
  30.   // wait() method know how to optimize itself.  Be sure to
  31.   // set this with the <waiters_lock_> held.
  32.       was_broadcast_ = 1;
  33.   have_waiters = 1;
  34. }
  35. waiters_lock_.unlock();
  36. int result = 0;
  37. if (have_waiters)
  38.     {
  39. // Wake up all the waiters.
  40. ReleaseSemaphore(sema_,waiters_,NULL);
  41. WaitForSingleObject(waiters_done_,INFINITE) ;
  42. // This is okay, even without the <waiters_lock_> held because
  43. // no other waiter threads can wake up to access it.
  44. was_broadcast_ = 0;
  45.     }
  46. return result;
  47. }
  48. inline int wait (Mutex& external_mutex)
  49. {
  50. // Prevent race conditions on the <waiters_> count.
  51. waiters_lock_.lock();
  52. waiters_++;
  53. waiters_lock_.unlock();
  54. int result = 0;
  55.         external_mutex.unlock();
  56. DWORD dwResult = WaitForSingleObject(sema_,INFINITE);
  57. if(dwResult != WAIT_OBJECT_0)
  58. result = (int)dwResult;
  59. // Reacquire lock to avoid race conditions on the <waiters_> count.
  60. waiters_lock_.lock();
  61. // We're ready to return, so there's one less waiter.
  62. waiters_--;
  63. int last_waiter = was_broadcast_ && waiters_ == 0;
  64. // Release the lock so that other collaborating threads can make
  65. // progress.
  66. waiters_lock_.unlock();
  67. if (result != -1 && last_waiter)
  68. SetEvent(waiters_done_);
  69. external_mutex.lock();
  70. return result;
  71. }
  72. protected:
  73.   /// Serialize access to the waiters count.
  74.   Mutex waiters_lock_;
  75.   /// Queue up threads waiting for the condition to become signaled.
  76.   HANDLE sema_;
  77.   /**
  78.    * An auto reset event used by the broadcast/signal thread to wait
  79.    * for the waiting thread(s) to wake up and get a chance at the
  80.    * semaphore.
  81.    */
  82.   HANDLE waiters_done_;
  83.   /// Keeps track of whether we were broadcasting or just signaling.
  84.   size_t was_broadcast_;
  85. };
  86. #else
  87. #include <pthread.h>
  88. namespace Producer {
  89. class PR_EXPORT Condition
  90. {
  91. public:
  92. /// number of waiters.
  93. Condition(long max)
  94. {
  95.         pthread_cond_init( &_cond, 0L );
  96. }
  97. ~Condition()
  98. {
  99. }
  100. inline int broadcast ()
  101. {
  102. return pthread_cond_broadcast(&_cond);
  103. }
  104. inline int wait (Mutex& external_mutex)
  105. {
  106. return pthread_cond_wait(&_cond);
  107. }
  108. protected:
  109.    pthread_cond_t _cond;
  110. };
  111. #endif
  112. }
  113. #endif