Add missing windows conditions variable
Those are used by generic RW lock implementation. https://bugs.freedesktop.org/show_bug.cgi?id=96754
This commit is contained in:
		
				
					committed by
					
						 Arun Raghavan
						Arun Raghavan
					
				
			
			
				
	
			
			
			
						parent
						
							db2f422578
						
					
				
				
					commit
					6ad2f51e9e
				
			| @@ -2,6 +2,7 @@ noinst_LTLIBRARIES = libsystem_wrappers.la | |||||||
|  |  | ||||||
| noinst_HEADERS = include/aligned_array.h \ | noinst_HEADERS = include/aligned_array.h \ | ||||||
| 		 include/asm_defines.h \ | 		 include/asm_defines.h \ | ||||||
|  | 		 include/condition_variable_wrapper.h \ | ||||||
| 		 include/compile_assert_c.h \ | 		 include/compile_assert_c.h \ | ||||||
| 		 include/event_wrapper.h \ | 		 include/event_wrapper.h \ | ||||||
| 		 include/scoped_vector.h \ | 		 include/scoped_vector.h \ | ||||||
| @@ -42,27 +43,49 @@ libsystem_wrappers_la_SOURCES = include/aligned_malloc.h \ | |||||||
| 				source/trace_impl.h \ | 				source/trace_impl.h \ | ||||||
| 				source/trace_posix.h \ | 				source/trace_posix.h \ | ||||||
| 				source/trace_win.h | 				source/trace_win.h | ||||||
|  |  | ||||||
|  | EXTRA_DIST = BUILD.gn | ||||||
|  |  | ||||||
| if HAVE_POSIX | if HAVE_POSIX | ||||||
| libsystem_wrappers_la_SOURCES += source/critical_section_posix.cc \ | libsystem_wrappers_la_SOURCES += source/critical_section_posix.cc \ | ||||||
| 				 source/event_timer_posix.cc \ | 				 source/event_timer_posix.cc \ | ||||||
| 				 source/rw_lock_posix.cc \ | 				 source/rw_lock_posix.cc \ | ||||||
| 				 source/thread_posix.cc \ | 				 source/thread_posix.cc \ | ||||||
| 				 source/trace_posix.cc | 				 source/trace_posix.cc | ||||||
|  | else | ||||||
|  | EXTRA_DIST += source/critical_section_posix.cc \ | ||||||
|  | 			  source/event_timer_posix.cc \ | ||||||
|  | 			  source/rw_lock_posix.cc \ | ||||||
|  | 			  source/thread_posix.cc \ | ||||||
|  | 			  source/trace_posix.cc | ||||||
| endif | endif | ||||||
| if HAVE_WIN |  | ||||||
| libsystem_wrappers_la_SOURCES += source/critical_section_win.cc \ |  | ||||||
| 				 source/event_timer_win.cc \ |  | ||||||
| 				 source/rw_lock_win.cc \ |  | ||||||
| 				 source/rw_lock_generic.cc \ |  | ||||||
| 				 source/thread_win.cc \ |  | ||||||
| 				 source/trace_win.cc |  | ||||||
| endif |  | ||||||
| libsystem_wrappers_la_CXXFLAGS = $(AM_CXXFLAGS) $(COMMON_CXXFLAGS) |  | ||||||
|  |  | ||||||
| EXTRA_DIST = BUILD.gn \ | if HAVE_WIN | ||||||
|  | libsystem_wrappers_la_SOURCES += include/fix_interlocked_exchange_pointer_win.h \ | ||||||
| 				 source/critical_section_win.cc \ | 				 source/critical_section_win.cc \ | ||||||
|  | 				 source/condition_variable.cc \ | ||||||
|  | 				 source/condition_variable_event_win.cc \ | ||||||
|  | 				 source/condition_variable_event_win.h \ | ||||||
|  | 				 source/condition_variable_native_win.cc \ | ||||||
|  | 				 source/condition_variable_native_win.h \ | ||||||
|  | 				 source/event_timer_win.cc \ | ||||||
|  | 				 source/rw_lock_win.cc \ | ||||||
|  | 				 source/rw_lock_generic.cc \ | ||||||
|  | 				 source/thread_win.cc \ | ||||||
|  | 				 source/trace_win.cc | ||||||
|  | else | ||||||
|  | EXTRA_DIST += include/fix_interlocked_exchange_pointer_win.h \ | ||||||
|  | 	      source/critical_section_win.cc \ | ||||||
|  | 	      source/condition_variable.cc \ | ||||||
|  | 	      source/condition_variable_event_win.cc \ | ||||||
|  | 	      source/condition_variable_event_win.h \ | ||||||
|  | 	      source/condition_variable_native_win.cc \ | ||||||
|  | 	      source/condition_variable_native_win.h \ | ||||||
| 	      source/event_timer_win.cc \ | 	      source/event_timer_win.cc \ | ||||||
| 	      source/rw_lock_generic.cc \ | 	      source/rw_lock_generic.cc \ | ||||||
| 	      source/rw_lock_win.cc \ | 	      source/rw_lock_win.cc \ | ||||||
| 	      source/thread_win.cc \ | 	      source/thread_win.cc \ | ||||||
| 	      source/trace_win.cc | 	      source/trace_win.cc | ||||||
|  | endif | ||||||
|  |  | ||||||
|  | libsystem_wrappers_la_CXXFLAGS = $(AM_CXXFLAGS) $(COMMON_CXXFLAGS) | ||||||
|   | |||||||
							
								
								
									
										42
									
								
								webrtc/system_wrappers/include/condition_variable_wrapper.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								webrtc/system_wrappers/include/condition_variable_wrapper.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | |||||||
|  | /* | ||||||
|  |  *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. | ||||||
|  |  * | ||||||
|  |  *  Use of this source code is governed by a BSD-style license | ||||||
|  |  *  that can be found in the LICENSE file in the root of the source | ||||||
|  |  *  tree. An additional intellectual property rights grant can be found | ||||||
|  |  *  in the file PATENTS.  All contributing project authors may | ||||||
|  |  *  be found in the AUTHORS file in the root of the source tree. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #ifndef WEBRTC_SYSTEM_WRAPPERS_INCLUDE_CONDITION_VARIABLE_WRAPPER_H_ | ||||||
|  | #define WEBRTC_SYSTEM_WRAPPERS_INCLUDE_CONDITION_VARIABLE_WRAPPER_H_ | ||||||
|  |  | ||||||
|  | namespace webrtc { | ||||||
|  |  | ||||||
|  | class CriticalSectionWrapper; | ||||||
|  |  | ||||||
|  | class ConditionVariableWrapper { | ||||||
|  |  public: | ||||||
|  |   // Factory method, constructor disabled. | ||||||
|  |   static ConditionVariableWrapper* CreateConditionVariable(); | ||||||
|  |  | ||||||
|  |   virtual ~ConditionVariableWrapper() {} | ||||||
|  |  | ||||||
|  |   // Calling thread will atomically release crit_sect and wait until next | ||||||
|  |   // some other thread calls Wake() or WakeAll(). | ||||||
|  |   virtual void SleepCS(CriticalSectionWrapper& crit_sect) = 0; | ||||||
|  |  | ||||||
|  |   // Same as above but with a timeout. | ||||||
|  |   virtual bool SleepCS(CriticalSectionWrapper& crit_sect, | ||||||
|  |                        unsigned long max_time_in_ms) = 0; | ||||||
|  |  | ||||||
|  |   // Wakes one thread calling SleepCS(). | ||||||
|  |   virtual void Wake() = 0; | ||||||
|  |  | ||||||
|  |   // Wakes all threads calling SleepCS(). | ||||||
|  |   virtual void WakeAll() = 0; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | }  // namespace webrtc | ||||||
|  |  | ||||||
|  | #endif  // WEBRTC_SYSTEM_WRAPPERS_INCLUDE_CONDITION_VARIABLE_WRAPPER_H_ | ||||||
							
								
								
									
										41
									
								
								webrtc/system_wrappers/source/condition_variable.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								webrtc/system_wrappers/source/condition_variable.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | |||||||
|  | /* | ||||||
|  |  *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. | ||||||
|  |  * | ||||||
|  |  *  Use of this source code is governed by a BSD-style license | ||||||
|  |  *  that can be found in the LICENSE file in the root of the source | ||||||
|  |  *  tree. An additional intellectual property rights grant can be found | ||||||
|  |  *  in the file PATENTS.  All contributing project authors may | ||||||
|  |  *  be found in the AUTHORS file in the root of the source tree. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #include "webrtc/system_wrappers/include/condition_variable_wrapper.h" | ||||||
|  |  | ||||||
|  | #if defined(_WIN32) | ||||||
|  | #include <windows.h> | ||||||
|  | #include "webrtc/system_wrappers/source/condition_variable_event_win.h" | ||||||
|  | #include "webrtc/system_wrappers/source/condition_variable_native_win.h" | ||||||
|  | #elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC) | ||||||
|  | #include <pthread.h> | ||||||
|  | #include "webrtc/system_wrappers/source/condition_variable_posix.h" | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | namespace webrtc { | ||||||
|  |  | ||||||
|  | ConditionVariableWrapper* ConditionVariableWrapper::CreateConditionVariable() { | ||||||
|  | #if defined(_WIN32) | ||||||
|  |   // Try to create native condition variable implementation. | ||||||
|  |   ConditionVariableWrapper* ret_val = ConditionVariableNativeWin::Create(); | ||||||
|  |   if (!ret_val) { | ||||||
|  |     // Native condition variable implementation does not exist. Create generic | ||||||
|  |     // condition variable based on events. | ||||||
|  |     ret_val = new ConditionVariableEventWin(); | ||||||
|  |   } | ||||||
|  |   return ret_val; | ||||||
|  | #elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC) | ||||||
|  |   return ConditionVariablePosix::Create(); | ||||||
|  | #else | ||||||
|  |   return NULL; | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  |  | ||||||
|  | }  // namespace webrtc | ||||||
							
								
								
									
										195
									
								
								webrtc/system_wrappers/source/condition_variable_event_win.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										195
									
								
								webrtc/system_wrappers/source/condition_variable_event_win.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,195 @@ | |||||||
|  | /* | ||||||
|  | Source: | ||||||
|  | http://www1.cse.wustl.edu/~schmidt/ACE-copying.html | ||||||
|  |  | ||||||
|  | License: | ||||||
|  | Copyright and Licensing Information for ACE(TM), TAO(TM), CIAO(TM), DAnCE(TM), | ||||||
|  | and CoSMIC(TM) | ||||||
|  |  | ||||||
|  | ACE(TM), TAO(TM), CIAO(TM), DAnCE>(TM), and CoSMIC(TM) (henceforth referred to | ||||||
|  | as "DOC software") are copyrighted by Douglas C. Schmidt and his research | ||||||
|  | group at Washington University, University of California, Irvine, and | ||||||
|  | Vanderbilt University, Copyright (c) 1993-2009, all rights reserved. Since DOC | ||||||
|  | software is open-source, freely available software, you are free to use, | ||||||
|  | modify, copy, and distribute--perpetually and irrevocably--the DOC software | ||||||
|  | source code and object code produced from the source, as well as copy and | ||||||
|  | distribute modified versions of this software. You must, however, include this | ||||||
|  | copyright statement along with any code built using DOC software that you | ||||||
|  | release. No copyright statement needs to be provided if you just ship binary | ||||||
|  | executables of your software products. | ||||||
|  | You can use DOC software in commercial and/or binary software releases and are | ||||||
|  | under no obligation to redistribute any of your source code that is built | ||||||
|  | using DOC software. Note, however, that you may not misappropriate the DOC | ||||||
|  | software code, such as copyrighting it yourself or claiming authorship of the | ||||||
|  | DOC software code, in a way that will prevent DOC software from being | ||||||
|  | distributed freely using an open-source development model. You needn't inform | ||||||
|  | anyone that you're using DOC software in your software, though we encourage | ||||||
|  | you to let us know so we can promote your project in the DOC software success | ||||||
|  | stories. | ||||||
|  |  | ||||||
|  | The ACE, TAO, CIAO, DAnCE, and CoSMIC web sites are maintained by the DOC | ||||||
|  | Group at the Institute for Software Integrated Systems (ISIS) and the Center | ||||||
|  | for Distributed Object Computing of Washington University, St. Louis for the | ||||||
|  | development of open-source software as part of the open-source software | ||||||
|  | community. Submissions are provided by the submitter ``as is'' with no | ||||||
|  | warranties whatsoever, including any warranty of merchantability, | ||||||
|  | noninfringement of third party intellectual property, or fitness for any | ||||||
|  | particular purpose. In no event shall the submitter be liable for any direct, | ||||||
|  | indirect, special, exemplary, punitive, or consequential damages, including | ||||||
|  | without limitation, lost profits, even if advised of the possibility of such | ||||||
|  | damages. Likewise, DOC software is provided as is with no warranties of any | ||||||
|  | kind, including the warranties of design, merchantability, and fitness for a | ||||||
|  | particular purpose, noninfringement, or arising from a course of dealing, | ||||||
|  | usage or trade practice. Washington University, UC Irvine, Vanderbilt | ||||||
|  | University, their employees, and students shall have no liability with respect | ||||||
|  | to the infringement of copyrights, trade secrets or any patents by DOC | ||||||
|  | software or any part thereof. Moreover, in no event will Washington | ||||||
|  | University, UC Irvine, or Vanderbilt University, their employees, or students | ||||||
|  | be liable for any lost revenue or profits or other special, indirect and | ||||||
|  | consequential damages. | ||||||
|  |  | ||||||
|  | DOC software is provided with no support and without any obligation on the | ||||||
|  | part of Washington University, UC Irvine, Vanderbilt University, their | ||||||
|  | employees, or students to assist in its use, correction, modification, or | ||||||
|  | enhancement. A number of companies around the world provide commercial support | ||||||
|  | for DOC software, however. DOC software is Y2K-compliant, as long as the | ||||||
|  | underlying OS platform is Y2K-compliant. Likewise, DOC software is compliant | ||||||
|  | with the new US daylight savings rule passed by Congress as "The Energy Policy | ||||||
|  | Act of 2005," which established new daylight savings times (DST) rules for the | ||||||
|  | United States that expand DST as of March 2007. Since DOC software obtains | ||||||
|  | time/date and calendaring information from operating systems users will not be | ||||||
|  | affected by the new DST rules as long as they upgrade their operating systems | ||||||
|  | accordingly. | ||||||
|  |  | ||||||
|  | The names ACE(TM), TAO(TM), CIAO(TM), DAnCE(TM), CoSMIC(TM), Washington | ||||||
|  | University, UC Irvine, and Vanderbilt University, may not be used to endorse | ||||||
|  | or promote products or services derived from this source without express | ||||||
|  | written permission from Washington University, UC Irvine, or Vanderbilt | ||||||
|  | University. This license grants no permission to call products or services | ||||||
|  | derived from this source ACE(TM), TAO(TM), CIAO(TM), DAnCE(TM), or CoSMIC(TM), | ||||||
|  | nor does it grant permission for the name Washington University, UC Irvine, or | ||||||
|  | Vanderbilt University to appear in their names. | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  *  This source code contain modifications to the original source code | ||||||
|  |  *  which can be found here: | ||||||
|  |  *  http://www.cs.wustl.edu/~schmidt/win32-cv-1.html (section 3.2). | ||||||
|  |  *  Modifications: | ||||||
|  |  *  1) Dynamic detection of native support for condition variables. | ||||||
|  |  *  2) Use of WebRTC defined types and classes. Renaming of some functions. | ||||||
|  |  *  3) Introduction of a second event for wake all functionality. This prevents | ||||||
|  |  *     a thread from spinning on the same condition variable, preventing other | ||||||
|  |  *     threads from waking up. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #include "webrtc/system_wrappers/source/condition_variable_event_win.h" | ||||||
|  | #include "webrtc/system_wrappers/source/critical_section_win.h" | ||||||
|  |  | ||||||
|  | namespace webrtc { | ||||||
|  |  | ||||||
|  | ConditionVariableEventWin::ConditionVariableEventWin() : eventID_(WAKEALL_0) { | ||||||
|  |   memset(&num_waiters_[0], 0, sizeof(num_waiters_)); | ||||||
|  |  | ||||||
|  |   InitializeCriticalSection(&num_waiters_crit_sect_); | ||||||
|  |  | ||||||
|  |   events_[WAKEALL_0] = CreateEvent(NULL,  // no security attributes | ||||||
|  |                                    TRUE,  // manual-reset, sticky event | ||||||
|  |                                    FALSE,  // initial state non-signaled | ||||||
|  |                                    NULL);  // no name for event | ||||||
|  |  | ||||||
|  |   events_[WAKEALL_1] = CreateEvent(NULL,  // no security attributes | ||||||
|  |                                    TRUE,  // manual-reset, sticky event | ||||||
|  |                                    FALSE,  // initial state non-signaled | ||||||
|  |                                    NULL);  // no name for event | ||||||
|  |  | ||||||
|  |   events_[WAKE] = CreateEvent(NULL,  // no security attributes | ||||||
|  |                               FALSE,  // auto-reset, sticky event | ||||||
|  |                               FALSE,  // initial state non-signaled | ||||||
|  |                               NULL);  // no name for event | ||||||
|  | } | ||||||
|  |  | ||||||
|  | ConditionVariableEventWin::~ConditionVariableEventWin() { | ||||||
|  |   CloseHandle(events_[WAKE]); | ||||||
|  |   CloseHandle(events_[WAKEALL_1]); | ||||||
|  |   CloseHandle(events_[WAKEALL_0]); | ||||||
|  |  | ||||||
|  |   DeleteCriticalSection(&num_waiters_crit_sect_); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ConditionVariableEventWin::SleepCS(CriticalSectionWrapper& crit_sect) { | ||||||
|  |   SleepCS(crit_sect, INFINITE); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool ConditionVariableEventWin::SleepCS(CriticalSectionWrapper& crit_sect, | ||||||
|  |                                         unsigned long max_time_in_ms) { | ||||||
|  |   EnterCriticalSection(&num_waiters_crit_sect_); | ||||||
|  |  | ||||||
|  |   // Get the eventID for the event that will be triggered by next | ||||||
|  |   // WakeAll() call and start waiting for it. | ||||||
|  |   const EventWakeUpType eventID = | ||||||
|  |       (WAKEALL_0 == eventID_) ? WAKEALL_1 : WAKEALL_0; | ||||||
|  |  | ||||||
|  |   ++(num_waiters_[eventID]); | ||||||
|  |   LeaveCriticalSection(&num_waiters_crit_sect_); | ||||||
|  |  | ||||||
|  |   CriticalSectionWindows* cs = | ||||||
|  |       static_cast<CriticalSectionWindows*>(&crit_sect); | ||||||
|  |   LeaveCriticalSection(&cs->crit); | ||||||
|  |   HANDLE events[2]; | ||||||
|  |   events[0] = events_[WAKE]; | ||||||
|  |   events[1] = events_[eventID]; | ||||||
|  |   const DWORD result = WaitForMultipleObjects(2,  // Wait on 2 events. | ||||||
|  |                                               events, | ||||||
|  |                                               FALSE,  // Wait for either. | ||||||
|  |                                               max_time_in_ms); | ||||||
|  |  | ||||||
|  |   const bool ret_val = (result != WAIT_TIMEOUT); | ||||||
|  |  | ||||||
|  |   EnterCriticalSection(&num_waiters_crit_sect_); | ||||||
|  |   --(num_waiters_[eventID]); | ||||||
|  |  | ||||||
|  |   // Last waiter should only be true for WakeAll(). WakeAll() correspond | ||||||
|  |   // to position 1 in events[] -> (result == WAIT_OBJECT_0 + 1) | ||||||
|  |   const bool last_waiter = (result == WAIT_OBJECT_0 + 1) && | ||||||
|  |       (num_waiters_[eventID] == 0); | ||||||
|  |   LeaveCriticalSection(&num_waiters_crit_sect_); | ||||||
|  |  | ||||||
|  |   if (last_waiter) { | ||||||
|  |     // Reset/unset the WakeAll() event since all threads have been | ||||||
|  |     // released. | ||||||
|  |     ResetEvent(events_[eventID]); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   EnterCriticalSection(&cs->crit); | ||||||
|  |   return ret_val; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ConditionVariableEventWin::Wake() { | ||||||
|  |   EnterCriticalSection(&num_waiters_crit_sect_); | ||||||
|  |   const bool have_waiters = (num_waiters_[WAKEALL_0] > 0) || | ||||||
|  |       (num_waiters_[WAKEALL_1] > 0); | ||||||
|  |   LeaveCriticalSection(&num_waiters_crit_sect_); | ||||||
|  |  | ||||||
|  |   if (have_waiters) { | ||||||
|  |     SetEvent(events_[WAKE]); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ConditionVariableEventWin::WakeAll() { | ||||||
|  |   EnterCriticalSection(&num_waiters_crit_sect_); | ||||||
|  |  | ||||||
|  |   // Update current WakeAll() event | ||||||
|  |   eventID_ = (WAKEALL_0 == eventID_) ? WAKEALL_1 : WAKEALL_0; | ||||||
|  |  | ||||||
|  |   // Trigger current event | ||||||
|  |   const EventWakeUpType eventID = eventID_; | ||||||
|  |   const bool have_waiters = num_waiters_[eventID] > 0; | ||||||
|  |   LeaveCriticalSection(&num_waiters_crit_sect_); | ||||||
|  |  | ||||||
|  |   if (have_waiters) { | ||||||
|  |     SetEvent(events_[eventID]); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | }  // namespace webrtc | ||||||
							
								
								
									
										46
									
								
								webrtc/system_wrappers/source/condition_variable_event_win.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								webrtc/system_wrappers/source/condition_variable_event_win.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | |||||||
|  | /* | ||||||
|  |  *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. | ||||||
|  |  * | ||||||
|  |  *  Use of this source code is governed by a BSD-style license | ||||||
|  |  *  that can be found in the LICENSE file in the root of the source | ||||||
|  |  *  tree. An additional intellectual property rights grant can be found | ||||||
|  |  *  in the file PATENTS.  All contributing project authors may | ||||||
|  |  *  be found in the AUTHORS file in the root of the source tree. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_CONDITION_VARIABLE_EVENT_WIN_H_ | ||||||
|  | #define WEBRTC_SYSTEM_WRAPPERS_SOURCE_CONDITION_VARIABLE_EVENT_WIN_H_ | ||||||
|  |  | ||||||
|  | #include <windows.h> | ||||||
|  |  | ||||||
|  | #include "webrtc/system_wrappers/include/condition_variable_wrapper.h" | ||||||
|  |  | ||||||
|  | namespace webrtc { | ||||||
|  |  | ||||||
|  | class ConditionVariableEventWin : public ConditionVariableWrapper { | ||||||
|  |  public: | ||||||
|  |   ConditionVariableEventWin(); | ||||||
|  |   virtual ~ConditionVariableEventWin(); | ||||||
|  |  | ||||||
|  |   void SleepCS(CriticalSectionWrapper& crit_sect); | ||||||
|  |   bool SleepCS(CriticalSectionWrapper& crit_sect, unsigned long max_time_inMS); | ||||||
|  |   void Wake(); | ||||||
|  |   void WakeAll(); | ||||||
|  |  | ||||||
|  |  private: | ||||||
|  |   enum EventWakeUpType { | ||||||
|  |     WAKEALL_0   = 0, | ||||||
|  |     WAKEALL_1   = 1, | ||||||
|  |     WAKE        = 2, | ||||||
|  |     EVENT_COUNT = 3 | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   unsigned int     num_waiters_[2]; | ||||||
|  |   EventWakeUpType  eventID_; | ||||||
|  |   CRITICAL_SECTION num_waiters_crit_sect_; | ||||||
|  |   HANDLE           events_[EVENT_COUNT]; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | }  // namespace webrtc | ||||||
|  |  | ||||||
|  | #endif  // WEBRTC_SYSTEM_WRAPPERS_SOURCE_CONDITION_VARIABLE_EVENT_WIN_H_ | ||||||
							
								
								
									
										104
									
								
								webrtc/system_wrappers/source/condition_variable_native_win.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								webrtc/system_wrappers/source/condition_variable_native_win.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,104 @@ | |||||||
|  | /* | ||||||
|  |  *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. | ||||||
|  |  * | ||||||
|  |  *  Use of this source code is governed by a BSD-style license | ||||||
|  |  *  that can be found in the LICENSE file in the root of the source | ||||||
|  |  *  tree. An additional intellectual property rights grant can be found | ||||||
|  |  *  in the file PATENTS.  All contributing project authors may | ||||||
|  |  *  be found in the AUTHORS file in the root of the source tree. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #include "webrtc/system_wrappers/include/trace.h" | ||||||
|  | #include "webrtc/system_wrappers/source/condition_variable_native_win.h" | ||||||
|  | #include "webrtc/system_wrappers/source/critical_section_win.h" | ||||||
|  |  | ||||||
|  | namespace webrtc { | ||||||
|  |  | ||||||
|  | static HMODULE library = NULL; | ||||||
|  | static bool win_support_condition_variables_primitive = false; | ||||||
|  |  | ||||||
|  | PInitializeConditionVariable  PInitializeConditionVariable_; | ||||||
|  | PSleepConditionVariableCS     PSleepConditionVariableCS_; | ||||||
|  | PWakeConditionVariable        PWakeConditionVariable_; | ||||||
|  | PWakeAllConditionVariable     PWakeAllConditionVariable_; | ||||||
|  |  | ||||||
|  | typedef void (WINAPI *PInitializeConditionVariable)(PCONDITION_VARIABLE); | ||||||
|  | typedef BOOL (WINAPI *PSleepConditionVariableCS)(PCONDITION_VARIABLE, | ||||||
|  |                                                  PCRITICAL_SECTION, DWORD); | ||||||
|  | typedef void (WINAPI *PWakeConditionVariable)(PCONDITION_VARIABLE); | ||||||
|  | typedef void (WINAPI *PWakeAllConditionVariable)(PCONDITION_VARIABLE); | ||||||
|  |  | ||||||
|  | ConditionVariableNativeWin::ConditionVariableNativeWin() { | ||||||
|  | } | ||||||
|  |  | ||||||
|  | ConditionVariableNativeWin::~ConditionVariableNativeWin() { | ||||||
|  | } | ||||||
|  |  | ||||||
|  | ConditionVariableWrapper* ConditionVariableNativeWin::Create() { | ||||||
|  |   ConditionVariableNativeWin* ret_val = new ConditionVariableNativeWin(); | ||||||
|  |   if (!ret_val->Init()) { | ||||||
|  |     delete ret_val; | ||||||
|  |     return NULL; | ||||||
|  |   } | ||||||
|  |   return ret_val; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool ConditionVariableNativeWin::Init() { | ||||||
|  |   if (!library) { | ||||||
|  |     // Native implementation is supported on Vista+. | ||||||
|  |     library = LoadLibrary(TEXT("Kernel32.dll")); | ||||||
|  |     // TODO(henrike): this code results in an attempt to load the above dll | ||||||
|  |     // every time the previous attempt failed. Only try to load once. | ||||||
|  |     if (library) { | ||||||
|  |       // TODO(henrike): not thread safe as reading and writing to library is not | ||||||
|  |       // serialized. Fix. | ||||||
|  |       WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1, "Loaded Kernel.dll"); | ||||||
|  |  | ||||||
|  |       PInitializeConditionVariable_ = | ||||||
|  |           (PInitializeConditionVariable) GetProcAddress( | ||||||
|  |               library, "InitializeConditionVariable"); | ||||||
|  |       PSleepConditionVariableCS_ = (PSleepConditionVariableCS) GetProcAddress( | ||||||
|  |           library, "SleepConditionVariableCS"); | ||||||
|  |       PWakeConditionVariable_ = (PWakeConditionVariable) GetProcAddress( | ||||||
|  |           library, "WakeConditionVariable"); | ||||||
|  |       PWakeAllConditionVariable_ = (PWakeAllConditionVariable) GetProcAddress( | ||||||
|  |           library, "WakeAllConditionVariable"); | ||||||
|  |  | ||||||
|  |       if (PInitializeConditionVariable_ && PSleepConditionVariableCS_ | ||||||
|  |           && PWakeConditionVariable_ && PWakeAllConditionVariable_) { | ||||||
|  |         WEBRTC_TRACE( | ||||||
|  |             kTraceStateInfo, kTraceUtility, -1, | ||||||
|  |             "Loaded native condition variables"); | ||||||
|  |         win_support_condition_variables_primitive = true; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   if (!win_support_condition_variables_primitive) { | ||||||
|  |     return false; | ||||||
|  |   } | ||||||
|  |   PInitializeConditionVariable_(&condition_variable_); | ||||||
|  |   return true; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ConditionVariableNativeWin::SleepCS(CriticalSectionWrapper& crit_sect) { | ||||||
|  |   SleepCS(crit_sect, INFINITE); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool ConditionVariableNativeWin::SleepCS(CriticalSectionWrapper& crit_sect, | ||||||
|  |                                          unsigned long max_time_in_ms) { | ||||||
|  |   CriticalSectionWindows* cs = | ||||||
|  |       static_cast<CriticalSectionWindows*>(&crit_sect); | ||||||
|  |   BOOL ret_val = PSleepConditionVariableCS_(&condition_variable_, | ||||||
|  |                                             &(cs->crit), max_time_in_ms); | ||||||
|  |   return ret_val != 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ConditionVariableNativeWin::Wake() { | ||||||
|  |   PWakeConditionVariable_(&condition_variable_); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ConditionVariableNativeWin::WakeAll() { | ||||||
|  |   PWakeAllConditionVariable_(&condition_variable_); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | }  // namespace webrtc | ||||||
| @@ -0,0 +1,54 @@ | |||||||
|  | /* | ||||||
|  |  *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. | ||||||
|  |  * | ||||||
|  |  *  Use of this source code is governed by a BSD-style license | ||||||
|  |  *  that can be found in the LICENSE file in the root of the source | ||||||
|  |  *  tree. An additional intellectual property rights grant can be found | ||||||
|  |  *  in the file PATENTS.  All contributing project authors may | ||||||
|  |  *  be found in the AUTHORS file in the root of the source tree. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_CONDITION_VARIABLE_NATIVE_WIN_H_ | ||||||
|  | #define WEBRTC_SYSTEM_WRAPPERS_SOURCE_CONDITION_VARIABLE_NATIVE_WIN_H_ | ||||||
|  |  | ||||||
|  | #include <windows.h> | ||||||
|  |  | ||||||
|  | #include "webrtc/system_wrappers/include/condition_variable_wrapper.h" | ||||||
|  |  | ||||||
|  | namespace webrtc { | ||||||
|  |  | ||||||
|  | #if !defined CONDITION_VARIABLE_INIT | ||||||
|  | typedef struct RTL_CONDITION_VARIABLE_ { | ||||||
|  |   void* Ptr; | ||||||
|  | } RTL_CONDITION_VARIABLE, *PRTL_CONDITION_VARIABLE; | ||||||
|  |  | ||||||
|  | typedef RTL_CONDITION_VARIABLE CONDITION_VARIABLE, *PCONDITION_VARIABLE; | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | typedef void (WINAPI* PInitializeConditionVariable)(PCONDITION_VARIABLE); | ||||||
|  | typedef BOOL (WINAPI* PSleepConditionVariableCS)(PCONDITION_VARIABLE, | ||||||
|  |                                                  PCRITICAL_SECTION, DWORD); | ||||||
|  | typedef void (WINAPI* PWakeConditionVariable)(PCONDITION_VARIABLE); | ||||||
|  | typedef void (WINAPI* PWakeAllConditionVariable)(PCONDITION_VARIABLE); | ||||||
|  |  | ||||||
|  | class ConditionVariableNativeWin : public ConditionVariableWrapper { | ||||||
|  |  public: | ||||||
|  |   static ConditionVariableWrapper* Create(); | ||||||
|  |   virtual ~ConditionVariableNativeWin(); | ||||||
|  |  | ||||||
|  |   void SleepCS(CriticalSectionWrapper& crit_sect); | ||||||
|  |   bool SleepCS(CriticalSectionWrapper& crit_sect, unsigned long max_time_inMS); | ||||||
|  |   void Wake(); | ||||||
|  |   void WakeAll(); | ||||||
|  |  | ||||||
|  |  private: | ||||||
|  |   ConditionVariableNativeWin(); | ||||||
|  |  | ||||||
|  |   bool Init(); | ||||||
|  |  | ||||||
|  |   CONDITION_VARIABLE condition_variable_; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | }  // namespace webrtc | ||||||
|  |  | ||||||
|  | #endif  // WEBRTC_SYSTEM_WRAPPERS_SOURCE_CONDITION_VARIABLE_NATIVE_WIN_H_ | ||||||
		Reference in New Issue
	
	Block a user