| //===-- Condition.cpp -------------------------------------------*- C++ -*-===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include <errno.h> |
| |
| #include "lldb/Host/Condition.h" |
| #include "lldb/Host/TimeValue.h" |
| #include "lldb/Host/windows/windows.h" |
| |
| |
| using namespace lldb_private; |
| |
| //---------------------------------------------------------------------- |
| // Default constructor |
| // |
| // The default constructor will initialize a new pthread condition |
| // and maintain the condition in the object state. |
| //---------------------------------------------------------------------- |
| Condition::Condition () : |
| m_condition() |
| { |
| m_condition = static_cast<PCONDITION_VARIABLE>(malloc(sizeof(CONDITION_VARIABLE))); |
| InitializeConditionVariable(static_cast<PCONDITION_VARIABLE>(m_condition)); |
| } |
| |
| //---------------------------------------------------------------------- |
| // Destructor |
| // |
| // Destroys the pthread condition that the object owns. |
| //---------------------------------------------------------------------- |
| Condition::~Condition () |
| { |
| free(m_condition); |
| } |
| |
| //---------------------------------------------------------------------- |
| // Unblock all threads waiting for a condition variable |
| //---------------------------------------------------------------------- |
| int |
| Condition::Broadcast () |
| { |
| WakeAllConditionVariable(static_cast<PCONDITION_VARIABLE>(m_condition)); |
| return 0; |
| } |
| |
| //---------------------------------------------------------------------- |
| // Unblocks one thread waiting for the condition variable |
| //---------------------------------------------------------------------- |
| int |
| Condition::Signal () |
| { |
| WakeConditionVariable(static_cast<PCONDITION_VARIABLE>(m_condition)); |
| return 0; |
| } |
| |
| //---------------------------------------------------------------------- |
| // The Wait() function atomically blocks the current thread |
| // waiting on the owned condition variable, and unblocks the mutex |
| // specified by "mutex". The waiting thread unblocks only after |
| // another thread calls Signal(), or Broadcast() with the same |
| // condition variable, or if "abstime" is valid (non-NULL) this |
| // function will return when the system time reaches the time |
| // specified in "abstime". If "abstime" is NULL this function will |
| // wait for an infinite amount of time for the condition variable |
| // to be signaled or broadcasted. |
| // |
| // The current thread re-acquires the lock on "mutex". |
| //---------------------------------------------------------------------- |
| int |
| Condition::Wait (Mutex &mutex, const TimeValue *abstime, bool *timed_out) |
| { |
| DWORD wait = INFINITE; |
| if (abstime != NULL) { |
| int wval = (*abstime - TimeValue::Now()) / 1000000; |
| if (wval < 0) wval = 0; |
| |
| wait = wval; |
| } |
| |
| int err = SleepConditionVariableCS(static_cast<PCONDITION_VARIABLE>(m_condition), static_cast<PCRITICAL_SECTION>(mutex.m_mutex), wait); |
| |
| if (timed_out != NULL) |
| { |
| if ((err == 0) && GetLastError() == ERROR_TIMEOUT) |
| *timed_out = true; |
| else |
| *timed_out = false; |
| } |
| |
| return err == 0; |
| } |
| |