You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
	
	
		
			196 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			C++
		
	
		
		
			
		
	
	
			196 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			C++
		
	
| 
											10 years ago
										 | /*
 | ||
|  | 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
 |