// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/synchronization/condition_variable.h"

#include <windows.h>
#include <stack>

#include "base/compiler_specific.h"
#include "base/logging.h"
#include "base/synchronization/lock.h"
#include "base/threading/thread_restrictions.h"
#include "base/time/time.h"

namespace {
// We can't use the linker supported delay-load for kernel32 so all this
// cruft here is to manually late-bind the needed functions.
typedef void (WINAPI *InitializeConditionVariableFn)(PCONDITION_VARIABLE);
typedef BOOL (WINAPI *SleepConditionVariableCSFn)(PCONDITION_VARIABLE,
                                                  PCRITICAL_SECTION, DWORD);
typedef void (WINAPI *WakeConditionVariableFn)(PCONDITION_VARIABLE);
typedef void (WINAPI *WakeAllConditionVariableFn)(PCONDITION_VARIABLE);

InitializeConditionVariableFn initialize_condition_variable_fn;
SleepConditionVariableCSFn sleep_condition_variable_fn;
WakeConditionVariableFn wake_condition_variable_fn;
WakeAllConditionVariableFn wake_all_condition_variable_fn;

bool BindVistaCondVarFunctions() {
  HMODULE kernel32 = GetModuleHandleA("kernel32.dll");
  initialize_condition_variable_fn =
      reinterpret_cast<InitializeConditionVariableFn>(
          GetProcAddress(kernel32, "InitializeConditionVariable"));
  if (!initialize_condition_variable_fn)
    return false;
  sleep_condition_variable_fn =
      reinterpret_cast<SleepConditionVariableCSFn>(
          GetProcAddress(kernel32, "SleepConditionVariableCS"));
  if (!sleep_condition_variable_fn)
    return false;
  wake_condition_variable_fn =
      reinterpret_cast<WakeConditionVariableFn>(
          GetProcAddress(kernel32, "WakeConditionVariable"));
  if (!wake_condition_variable_fn)
    return false;
  wake_all_condition_variable_fn =
      reinterpret_cast<WakeAllConditionVariableFn>(
          GetProcAddress(kernel32, "WakeAllConditionVariable"));
  if (!wake_all_condition_variable_fn)
    return false;
  return true;
}

}  // namespace.

namespace base {
// Abstract base class of the pimpl idiom.
class ConditionVarImpl {
 public:
  virtual ~ConditionVarImpl() {};
  virtual void Wait() = 0;
  virtual void TimedWait(const TimeDelta& max_time) = 0;
  virtual void Broadcast() = 0;
  virtual void Signal() = 0;
};

///////////////////////////////////////////////////////////////////////////////
// Windows Vista and Win7 implementation.
///////////////////////////////////////////////////////////////////////////////

class WinVistaCondVar: public ConditionVarImpl {
 public:
  WinVistaCondVar(Lock* user_lock);
  ~WinVistaCondVar() {};
  // Overridden from ConditionVarImpl.
  virtual void Wait() OVERRIDE;
  virtual void TimedWait(const TimeDelta& max_time) OVERRIDE;
  virtual void Broadcast() OVERRIDE;
  virtual void Signal() OVERRIDE;

 private:
  base::Lock& user_lock_;
  CONDITION_VARIABLE cv_;
};

WinVistaCondVar::WinVistaCondVar(Lock* user_lock)
    : user_lock_(*user_lock) {
  initialize_condition_variable_fn(&cv_);
  DCHECK(user_lock);
}

void WinVistaCondVar::Wait() {
  TimedWait(TimeDelta::FromMilliseconds(INFINITE));
}

void WinVistaCondVar::TimedWait(const TimeDelta& max_time) {
  base::ThreadRestrictions::AssertWaitAllowed();
  DWORD timeout = static_cast<DWORD>(max_time.InMilliseconds());
  CRITICAL_SECTION* cs = user_lock_.lock_.native_handle();

#if !defined(NDEBUG)
  user_lock_.CheckHeldAndUnmark();
#endif

  if (FALSE == sleep_condition_variable_fn(&cv_, cs, timeout)) {
    DCHECK(GetLastError() != WAIT_TIMEOUT);
  }

#if !defined(NDEBUG)
  user_lock_.CheckUnheldAndMark();
#endif
}

void WinVistaCondVar::Broadcast() {
  wake_all_condition_variable_fn(&cv_);
}

void WinVistaCondVar::Signal() {
  wake_condition_variable_fn(&cv_);
}

///////////////////////////////////////////////////////////////////////////////
// Windows XP implementation.
///////////////////////////////////////////////////////////////////////////////

class WinXPCondVar : public ConditionVarImpl {
 public:
  WinXPCondVar(Lock* user_lock);
  ~WinXPCondVar();
  // Overridden from ConditionVarImpl.
  virtual void Wait() OVERRIDE;
  virtual void TimedWait(const TimeDelta& max_time) OVERRIDE;
  virtual void Broadcast() OVERRIDE;
  virtual void Signal() OVERRIDE;

  // Define Event class that is used to form circularly linked lists.
  // The list container is an element with NULL as its handle_ value.
  // The actual list elements have a non-zero handle_ value.
  // All calls to methods MUST be done under protection of a lock so that links
  // can be validated.  Without the lock, some links might asynchronously
  // change, and the assertions would fail (as would list change operations).
  class Event {
   public:
    // Default constructor with no arguments creates a list container.
    Event();
    ~Event();

    // InitListElement transitions an instance from a container, to an element.
    void InitListElement();

    // Methods for use on lists.
    bool IsEmpty() const;
    void PushBack(Event* other);
    Event* PopFront();
    Event* PopBack();

    // Methods for use on list elements.
    // Accessor method.
    HANDLE handle() const;
    // Pull an element from a list (if it's in one).
    Event* Extract();

    // Method for use on a list element or on a list.
    bool IsSingleton() const;

   private:
    // Provide pre/post conditions to validate correct manipulations.
    bool ValidateAsDistinct(Event* other) const;
    bool ValidateAsItem() const;
    bool ValidateAsList() const;
    bool ValidateLinks() const;

    HANDLE handle_;
    Event* next_;
    Event* prev_;
    DISALLOW_COPY_AND_ASSIGN(Event);
  };

  // Note that RUNNING is an unlikely number to have in RAM by accident.
  // This helps with defensive destructor coding in the face of user error.
  enum RunState { SHUTDOWN = 0, RUNNING = 64213 };

  // Internal implementation methods supporting Wait().
  Event* GetEventForWaiting();
  void RecycleEvent(Event* used_event);

  RunState run_state_;

  // Private critical section for access to member data.
  base::Lock internal_lock_;

  // Lock that is acquired before calling Wait().
  base::Lock& user_lock_;

  // Events that threads are blocked on.
  Event waiting_list_;

  // Free list for old events.
  Event recycling_list_;
  int recycling_list_size_;

  // The number of allocated, but not yet deleted events.
  int allocation_counter_;
};

WinXPCondVar::WinXPCondVar(Lock* user_lock)
    : user_lock_(*user_lock),
      run_state_(RUNNING),
      allocation_counter_(0),
      recycling_list_size_(0) {
  DCHECK(user_lock);
}

WinXPCondVar::~WinXPCondVar() {
  AutoLock auto_lock(internal_lock_);
  run_state_ = SHUTDOWN;  // Prevent any more waiting.

  DCHECK_EQ(recycling_list_size_, allocation_counter_);
  if (recycling_list_size_ != allocation_counter_) {  // Rare shutdown problem.
    // There are threads of execution still in this->TimedWait() and yet the
    // caller has instigated the destruction of this instance :-/.
    // A common reason for such "overly hasty" destruction is that the caller
    // was not willing to wait for all the threads to terminate.  Such hasty
    // actions are a violation of our usage contract, but we'll give the
    // waiting thread(s) one last chance to exit gracefully (prior to our
    // destruction).
    // Note: waiting_list_ *might* be empty, but recycling is still pending.
    AutoUnlock auto_unlock(internal_lock_);
    Broadcast();  // Make sure all waiting threads have been signaled.
    Sleep(10);  // Give threads a chance to grab internal_lock_.
    // All contained threads should be blocked on user_lock_ by now :-).
  }  // Reacquire internal_lock_.

  DCHECK_EQ(recycling_list_size_, allocation_counter_);
}

void WinXPCondVar::Wait() {
  // Default to "wait forever" timing, which means have to get a Signal()
  // or Broadcast() to come out of this wait state.
  TimedWait(TimeDelta::FromMilliseconds(INFINITE));
}

void WinXPCondVar::TimedWait(const TimeDelta& max_time) {
  base::ThreadRestrictions::AssertWaitAllowed();
  Event* waiting_event;
  HANDLE handle;
  {
    AutoLock auto_lock(internal_lock_);
    if (RUNNING != run_state_) return;  // Destruction in progress.
    waiting_event = GetEventForWaiting();
    handle = waiting_event->handle();
    DCHECK(handle);
  }  // Release internal_lock.

  {
    AutoUnlock unlock(user_lock_);  // Release caller's lock
    WaitForSingleObject(handle, static_cast<DWORD>(max_time.InMilliseconds()));
    // Minimize spurious signal creation window by recycling asap.
    AutoLock auto_lock(internal_lock_);
    RecycleEvent(waiting_event);
    // Release internal_lock_
  }  // Reacquire callers lock to depth at entry.
}

// Broadcast() is guaranteed to signal all threads that were waiting (i.e., had
// a cv_event internally allocated for them) before Broadcast() was called.
void WinXPCondVar::Broadcast() {
  std::stack<HANDLE> handles;  // See FAQ-question-10.
  {
    AutoLock auto_lock(internal_lock_);
    if (waiting_list_.IsEmpty())
      return;
    while (!waiting_list_.IsEmpty())
      // This is not a leak from waiting_list_.  See FAQ-question 12.
      handles.push(waiting_list_.PopBack()->handle());
  }  // Release internal_lock_.
  while (!handles.empty()) {
    SetEvent(handles.top());
    handles.pop();
  }
}

// Signal() will select one of the waiting threads, and signal it (signal its
// cv_event).  For better performance we signal the thread that went to sleep
// most recently (LIFO).  If we want fairness, then we wake the thread that has
// been sleeping the longest (FIFO).
void WinXPCondVar::Signal() {
  HANDLE handle;
  {
    AutoLock auto_lock(internal_lock_);
    if (waiting_list_.IsEmpty())
      return;  // No one to signal.
    // Only performance option should be used.
    // This is not a leak from waiting_list.  See FAQ-question 12.
     handle = waiting_list_.PopBack()->handle();  // LIFO.
  }  // Release internal_lock_.
  SetEvent(handle);
}

// GetEventForWaiting() provides a unique cv_event for any caller that needs to
// wait.  This means that (worst case) we may over time create as many cv_event
// objects as there are threads simultaneously using this instance's Wait()
// functionality.
WinXPCondVar::Event* WinXPCondVar::GetEventForWaiting() {
  // We hold internal_lock, courtesy of Wait().
  Event* cv_event;
  if (0 == recycling_list_size_) {
    DCHECK(recycling_list_.IsEmpty());
    cv_event = new Event();
    cv_event->InitListElement();
    allocation_counter_++;
    DCHECK(cv_event->handle());
  } else {
    cv_event = recycling_list_.PopFront();
    recycling_list_size_--;
  }
  waiting_list_.PushBack(cv_event);
  return cv_event;
}

// RecycleEvent() takes a cv_event that was previously used for Wait()ing, and
// recycles it for use in future Wait() calls for this or other threads.
// Note that there is a tiny chance that the cv_event is still signaled when we
// obtain it, and that can cause spurious signals (if/when we re-use the
// cv_event), but such is quite rare (see FAQ-question-5).
void WinXPCondVar::RecycleEvent(Event* used_event) {
  // We hold internal_lock, courtesy of Wait().
  // If the cv_event timed out, then it is necessary to remove it from
  // waiting_list_.  If it was selected by Broadcast() or Signal(), then it is
  // already gone.
  used_event->Extract();  // Possibly redundant
  recycling_list_.PushBack(used_event);
  recycling_list_size_++;
}
//------------------------------------------------------------------------------
// The next section provides the implementation for the private Event class.
//------------------------------------------------------------------------------

// Event provides a doubly-linked-list of events for use exclusively by the
// ConditionVariable class.

// This custom container was crafted because no simple combination of STL
// classes appeared to support the functionality required.  The specific
// unusual requirement for a linked-list-class is support for the Extract()
// method, which can remove an element from a list, potentially for insertion
// into a second list.  Most critically, the Extract() method is idempotent,
// turning the indicated element into an extracted singleton whether it was
// contained in a list or not.  This functionality allows one (or more) of
// threads to do the extraction.  The iterator that identifies this extractable
// element (in this case, a pointer to the list element) can be used after
// arbitrary manipulation of the (possibly) enclosing list container.  In
// general, STL containers do not provide iterators that can be used across
// modifications (insertions/extractions) of the enclosing containers, and
// certainly don't provide iterators that can be used if the identified
// element is *deleted* (removed) from the container.

// It is possible to use multiple redundant containers, such as an STL list,
// and an STL map, to achieve similar container semantics.  This container has
// only O(1) methods, while the corresponding (multiple) STL container approach
// would have more complex O(log(N)) methods (yeah... N isn't that large).
// Multiple containers also makes correctness more difficult to assert, as
// data is redundantly stored and maintained, which is generally evil.

WinXPCondVar::Event::Event() : handle_(0) {
  next_ = prev_ = this;  // Self referencing circular.
}

WinXPCondVar::Event::~Event() {
  if (0 == handle_) {
    // This is the list holder
    while (!IsEmpty()) {
      Event* cv_event = PopFront();
      DCHECK(cv_event->ValidateAsItem());
      delete cv_event;
    }
  }
  DCHECK(IsSingleton());
  if (0 != handle_) {
    int ret_val = CloseHandle(handle_);
    DCHECK(ret_val);
  }
}

// Change a container instance permanently into an element of a list.
void WinXPCondVar::Event::InitListElement() {
  DCHECK(!handle_);
  handle_ = CreateEvent(NULL, false, false, NULL);
  DCHECK(handle_);
}

// Methods for use on lists.
bool WinXPCondVar::Event::IsEmpty() const {
  DCHECK(ValidateAsList());
  return IsSingleton();
}

void WinXPCondVar::Event::PushBack(Event* other) {
  DCHECK(ValidateAsList());
  DCHECK(other->ValidateAsItem());
  DCHECK(other->IsSingleton());
  // Prepare other for insertion.
  other->prev_ = prev_;
  other->next_ = this;
  // Cut into list.
  prev_->next_ = other;
  prev_ = other;
  DCHECK(ValidateAsDistinct(other));
}

WinXPCondVar::Event* WinXPCondVar::Event::PopFront() {
  DCHECK(ValidateAsList());
  DCHECK(!IsSingleton());
  return next_->Extract();
}

WinXPCondVar::Event* WinXPCondVar::Event::PopBack() {
  DCHECK(ValidateAsList());
  DCHECK(!IsSingleton());
  return prev_->Extract();
}

// Methods for use on list elements.
// Accessor method.
HANDLE WinXPCondVar::Event::handle() const {
  DCHECK(ValidateAsItem());
  return handle_;
}

// Pull an element from a list (if it's in one).
WinXPCondVar::Event* WinXPCondVar::Event::Extract() {
  DCHECK(ValidateAsItem());
  if (!IsSingleton()) {
    // Stitch neighbors together.
    next_->prev_ = prev_;
    prev_->next_ = next_;
    // Make extractee into a singleton.
    prev_ = next_ = this;
  }
  DCHECK(IsSingleton());
  return this;
}

// Method for use on a list element or on a list.
bool WinXPCondVar::Event::IsSingleton() const {
  DCHECK(ValidateLinks());
  return next_ == this;
}

// Provide pre/post conditions to validate correct manipulations.
bool WinXPCondVar::Event::ValidateAsDistinct(Event* other) const {
  return ValidateLinks() && other->ValidateLinks() && (this != other);
}

bool WinXPCondVar::Event::ValidateAsItem() const {
  return (0 != handle_) && ValidateLinks();
}

bool WinXPCondVar::Event::ValidateAsList() const {
  return (0 == handle_) && ValidateLinks();
}

bool WinXPCondVar::Event::ValidateLinks() const {
  // Make sure both of our neighbors have links that point back to us.
  // We don't do the O(n) check and traverse the whole loop, and instead only
  // do a local check to (and returning from) our immediate neighbors.
  return (next_->prev_ == this) && (prev_->next_ == this);
}


/*
FAQ On WinXPCondVar subtle implementation details:

1) What makes this problem subtle?  Please take a look at "Strategies
for Implementing POSIX Condition Variables on Win32" by Douglas
C. Schmidt and Irfan Pyarali.
http://www.cs.wustl.edu/~schmidt/win32-cv-1.html It includes
discussions of numerous flawed strategies for implementing this
functionality.  I'm not convinced that even the final proposed
implementation has semantics that are as nice as this implementation
(especially with regard to Broadcast() and the impact on threads that
try to Wait() after a Broadcast() has been called, but before all the
original waiting threads have been signaled).

2) Why can't you use a single wait_event for all threads that call
Wait()?  See FAQ-question-1, or consider the following: If a single
event were used, then numerous threads calling Wait() could release
their cs locks, and be preempted just before calling
WaitForSingleObject().  If a call to Broadcast() was then presented on
a second thread, it would be impossible to actually signal all
waiting(?) threads.  Some number of SetEvent() calls *could* be made,
but there could be no guarantee that those led to to more than one
signaled thread (SetEvent()'s may be discarded after the first!), and
there could be no guarantee that the SetEvent() calls didn't just
awaken "other" threads that hadn't even started waiting yet (oops).
Without any limit on the number of requisite SetEvent() calls, the
system would be forced to do many such calls, allowing many new waits
to receive spurious signals.

3) How does this implementation cause spurious signal events?  The
cause in this implementation involves a race between a signal via
time-out and a signal via Signal() or Broadcast().  The series of
actions leading to this are:

a) Timer fires, and a waiting thread exits the line of code:

    WaitForSingleObject(waiting_event, max_time.InMilliseconds());

b) That thread (in (a)) is randomly pre-empted after the above line,
leaving the waiting_event reset (unsignaled) and still in the
waiting_list_.

c) A call to Signal() (or Broadcast()) on a second thread proceeds, and
selects the waiting cv_event (identified in step (b)) as the event to revive
via a call to SetEvent().

d) The Signal() method (step c) calls SetEvent() on waiting_event (step b).

e) The waiting cv_event (step b) is now signaled, but no thread is
waiting on it.

f) When that waiting_event (step b) is reused, it will immediately
be signaled (spuriously).


4) Why do you recycle events, and cause spurious signals?  First off,
the spurious events are very rare.  They can only (I think) appear
when the race described in FAQ-question-3 takes place.  This should be
very rare.  Most(?)  uses will involve only timer expiration, or only
Signal/Broadcast() actions.  When both are used, it will be rare that
the race will appear, and it would require MANY Wait() and signaling
activities.  If this implementation did not recycle events, then it
would have to create and destroy events for every call to Wait().
That allocation/deallocation and associated construction/destruction
would be costly (per wait), and would only be a rare benefit (when the
race was "lost" and a spurious signal took place). That would be bad
(IMO) optimization trade-off.  Finally, such spurious events are
allowed by the specification of condition variables (such as
implemented in Vista), and hence it is better if any user accommodates
such spurious events (see usage note in condition_variable.h).

5) Why don't you reset events when you are about to recycle them, or
about to reuse them, so that the spurious signals don't take place?
The thread described in FAQ-question-3 step c may be pre-empted for an
arbitrary length of time before proceeding to step d.  As a result,
the wait_event may actually be re-used *before* step (e) is reached.
As a result, calling reset would not help significantly.

6) How is it that the callers lock is released atomically with the
entry into a wait state?  We commit to the wait activity when we
allocate the wait_event for use in a given call to Wait().  This
allocation takes place before the caller's lock is released (and
actually before our internal_lock_ is released).  That allocation is
the defining moment when "the wait state has been entered," as that
thread *can* now be signaled by a call to Broadcast() or Signal().
Hence we actually "commit to wait" before releasing the lock, making
the pair effectively atomic.

8) Why do you need to lock your data structures during waiting, as the
caller is already in possession of a lock?  We need to Acquire() and
Release() our internal lock during Signal() and Broadcast().  If we tried
to use a callers lock for this purpose, we might conflict with their
external use of the lock.  For example, the caller may use to consistently
hold a lock on one thread while calling Signal() on another, and that would
block Signal().

9) Couldn't a more efficient implementation be provided if you
preclude using more than one external lock in conjunction with a
single ConditionVariable instance?  Yes, at least it could be viewed
as a simpler API (since you don't have to reiterate the lock argument
in each Wait() call).  One of the constructors now takes a specific
lock as an argument, and a there are corresponding Wait() calls that
don't specify a lock now.  It turns that the resulting implmentation
can't be made more efficient, as the internal lock needs to be used by
Signal() and Broadcast(), to access internal data structures.  As a
result, I was not able to utilize the user supplied lock (which is
being used by the user elsewhere presumably) to protect the private
member access.

9) Since you have a second lock, how can be be sure that there is no
possible deadlock scenario?  Our internal_lock_ is always the last
lock acquired, and the first one released, and hence a deadlock (due
to critical section problems) is impossible as a consequence of our
lock.

10) When doing a Broadcast(), why did you copy all the events into
an STL queue, rather than making a linked-loop, and iterating over it?
The iterating during Broadcast() is done so outside the protection
of the internal lock. As a result, other threads, such as the thread
wherein a related event is waiting, could asynchronously manipulate
the links around a cv_event.  As a result, the link structure cannot
be used outside a lock.  Broadcast() could iterate over waiting
events by cycling in-and-out of the protection of the internal_lock,
but that appears more expensive than copying the list into an STL
stack.

11) Why did the lock.h file need to be modified so much for this
change?  Central to a Condition Variable is the atomic release of a
lock during a Wait().  This places Wait() functionality exactly
mid-way between the two classes, Lock and Condition Variable.  Given
that there can be nested Acquire()'s of locks, and Wait() had to
Release() completely a held lock, it was necessary to augment the Lock
class with a recursion counter. Even more subtle is the fact that the
recursion counter (in a Lock) must be protected, as many threads can
access it asynchronously.  As a positive fallout of this, there are
now some DCHECKS to be sure no one Release()s a Lock more than they
Acquire()ed it, and there is ifdef'ed functionality that can detect
nested locks (legal under windows, but not under Posix).

12) Why is it that the cv_events removed from list in Broadcast() and Signal()
are not leaked?  How are they recovered??  The cv_events that appear to leak are
taken from the waiting_list_.  For each element in that list, there is currently
a thread in or around the WaitForSingleObject() call of Wait(), and those
threads have references to these otherwise leaked events. They are passed as
arguments to be recycled just aftre returning from WaitForSingleObject().

13) Why did you use a custom container class (the linked list), when STL has
perfectly good containers, such as an STL list?  The STL list, as with any
container, does not guarantee the utility of an iterator across manipulation
(such as insertions and deletions) of the underlying container.  The custom
double-linked-list container provided that assurance.  I don't believe any
combination of STL containers provided the services that were needed at the same
O(1) efficiency as the custom linked list.  The unusual requirement
for the container class is that a reference to an item within a container (an
iterator) needed to be maintained across an arbitrary manipulation of the
container.  This requirement exposes itself in the Wait() method, where a
waiting_event must be selected prior to the WaitForSingleObject(), and then it
must be used as part of recycling to remove the related instance from the
waiting_list.  A hash table (STL map) could be used, but I was embarrased to
use a complex and relatively low efficiency container when a doubly linked list
provided O(1) performance in all required operations.  Since other operations
to provide performance-and/or-fairness required queue (FIFO) and list (LIFO)
containers, I would also have needed to use an STL list/queue as well as an STL
map.  In the end I decided it would be "fun" to just do it right, and I
put so many assertions (DCHECKs) into the container class that it is trivial to
code review and validate its correctness.

*/

ConditionVariable::ConditionVariable(Lock* user_lock)
    : impl_(NULL) {
  static bool use_vista_native_cv = BindVistaCondVarFunctions();
  if (use_vista_native_cv)
    impl_= new WinVistaCondVar(user_lock);
  else
    impl_ = new WinXPCondVar(user_lock);
}

ConditionVariable::~ConditionVariable() {
  delete impl_;
}

void ConditionVariable::Wait() {
  impl_->Wait();
}

void ConditionVariable::TimedWait(const TimeDelta& max_time) {
  impl_->TimedWait(max_time);
}

void ConditionVariable::Broadcast() {
  impl_->Broadcast();
}

void ConditionVariable::Signal() {
  impl_->Signal();
}

}  // namespace base
