| /* |
| 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/include/critical_section_wrapper.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(CRITICAL_SECTION* crit_sect) { |
| SleepCS(crit_sect, INFINITE); |
| } |
| |
| bool ConditionVariableEventWin::SleepCS(CRITICAL_SECTION* 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_); |
| |
| LeaveCriticalSection(crit_sect); |
| 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(crit_sect); |
| 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 |