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

并行计算

开发平台:

Visual C++

  1. //
  2. // OpenThread library, Copyright (C) 2002 - 2003  The Open Thread Group
  3. //
  4. // This library is free software; you can redistribute it and/or
  5. // modify it under the terms of the GNU Lesser General Public
  6. // License as published by the Free Software Foundation; either
  7. // version 2.1 of the License, or (at your option) any later version.
  8. //
  9. // This library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12. // Lesser General Public License for more details.
  13. // 
  14. // You should have received a copy of the GNU Lesser General Public
  15. // License along with this library; if not, write to the Free Software
  16. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  17. //
  18. //
  19. // WIN32ConditionPrivateData.h - Private data structure for Condition
  20. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  21. //
  22. #ifndef _WIN32CONDITIONPRIVATEDATA_H_
  23. #define _WIN32CONDITIONPRIVATEDATA_H_
  24. #ifndef _WINDOWS_
  25. #define WIN32_LEAN_AND_MEAN
  26. #include <windows.h>
  27. #endif
  28. #define InterlockedGet(x) InterlockedExchangeAdd(x,0)
  29. namespace OpenThreads {
  30. class Condition;
  31. class Win32ConditionPrivateData {
  32. public:
  33. friend class Condition;
  34. /// number of waiters.
  35. long waiters_;
  36. Win32ConditionPrivateData ()
  37. {
  38. waiters_ = 0;
  39. sema_ = CreateSemaphore(NULL,0,0x7fffffff,NULL);
  40. waiters_done_ = CreateEvent(NULL,FALSE,FALSE,NULL);
  41. }
  42. ~Win32ConditionPrivateData ();
  43. inline int broadcast ()
  44. {
  45.        int have_waiters = 0;
  46. long w = InterlockedGet(&waiters_);
  47. if (w > 0)
  48. {
  49.   // we are broadcasting.  
  50.       was_broadcast_ = 1;
  51.   have_waiters = 1;
  52. }
  53. int result = 0;
  54. if (have_waiters)
  55.     {
  56. // Wake up all the waiters.
  57. ReleaseSemaphore(sema_,waiters_,NULL);
  58. WaitForSingleObject(waiters_done_,INFINITE) ;
  59. //end of broadcasting
  60. was_broadcast_ = 0;
  61.     }
  62. return result;
  63. }
  64. inline int signal()
  65. {
  66. long w = InterlockedGet(&waiters_);
  67.     int have_waiters = w > 0;
  68.  
  69. int result = 0;
  70. if (have_waiters)
  71.     {
  72. if( !ReleaseSemaphore(sema_,1,NULL) )
  73. result = -1;
  74.     }
  75. return result;
  76. }
  77. inline int wait (Mutex& external_mutex, long timeout_ms)
  78. {
  79. // Prevent race conditions on the <waiters_> count.
  80. InterlockedIncrement(&waiters_);
  81. int result = 0;
  82.         external_mutex.unlock();
  83. DWORD dwResult = WaitForSingleObject(sema_,timeout_ms);
  84. if(dwResult != WAIT_OBJECT_0)
  85. result = (int)dwResult;
  86. // We're ready to return, so there's one less waiter.
  87. InterlockedDecrement(&waiters_);
  88. long w = InterlockedGet(&waiters_);
  89. int last_waiter = was_broadcast_ && w == 0;
  90. if (result != -1 && last_waiter)
  91. SetEvent(waiters_done_);
  92. external_mutex.lock();
  93. return result;
  94. }
  95. protected:
  96.   /// Serialize access to the waiters count.
  97.   /// Mutex waiters_lock_;
  98.   /// Queue up threads waiting for the condition to become signaled.
  99.   HANDLE sema_;
  100.   /**
  101.    * An auto reset event used by the broadcast/signal thread to wait
  102.    * for the waiting thread(s) to wake up and get a chance at the
  103.    * semaphore.
  104.    */
  105.   HANDLE waiters_done_;
  106.   /// Keeps track of whether we were broadcasting or just signaling.
  107.   size_t was_broadcast_;
  108. };
  109. #undef InterlockedGet
  110. }
  111. #endif // !_WIN32CONDITIONPRIVATEDATA_H_