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++
		
	
| /*
 | |
| 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
 |