1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/ipc/chromium/src/base/waitable_event_win.cc Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,97 @@ 1.4 +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1.5 +// Use of this source code is governed by a BSD-style license that can be 1.6 +// found in the LICENSE file. 1.7 + 1.8 +#include "base/waitable_event.h" 1.9 + 1.10 +#include <math.h> 1.11 +#include <windows.h> 1.12 + 1.13 +#include "base/logging.h" 1.14 +#include "base/time.h" 1.15 + 1.16 +namespace base { 1.17 + 1.18 +WaitableEvent::WaitableEvent(bool manual_reset, bool signaled) 1.19 + : handle_(CreateEvent(NULL, manual_reset, signaled, NULL)) { 1.20 + // We're probably going to crash anyways if this is ever NULL, so we might as 1.21 + // well make our stack reports more informative by crashing here. 1.22 + CHECK(handle_); 1.23 +} 1.24 + 1.25 +WaitableEvent::WaitableEvent(HANDLE handle) 1.26 + : handle_(handle) { 1.27 + CHECK(handle) << "Tried to create WaitableEvent from NULL handle"; 1.28 +} 1.29 + 1.30 +WaitableEvent::~WaitableEvent() { 1.31 + CloseHandle(handle_); 1.32 +} 1.33 + 1.34 +HANDLE WaitableEvent::Release() { 1.35 + HANDLE rv = handle_; 1.36 + handle_ = INVALID_HANDLE_VALUE; 1.37 + return rv; 1.38 +} 1.39 + 1.40 +void WaitableEvent::Reset() { 1.41 + ResetEvent(handle_); 1.42 +} 1.43 + 1.44 +void WaitableEvent::Signal() { 1.45 + SetEvent(handle_); 1.46 +} 1.47 + 1.48 +bool WaitableEvent::IsSignaled() { 1.49 + return TimedWait(TimeDelta::FromMilliseconds(0)); 1.50 +} 1.51 + 1.52 +bool WaitableEvent::Wait() { 1.53 + DWORD result = WaitForSingleObject(handle_, INFINITE); 1.54 + // It is most unexpected that this should ever fail. Help consumers learn 1.55 + // about it if it should ever fail. 1.56 + DCHECK(result == WAIT_OBJECT_0) << "WaitForSingleObject failed"; 1.57 + return result == WAIT_OBJECT_0; 1.58 +} 1.59 + 1.60 +bool WaitableEvent::TimedWait(const TimeDelta& max_time) { 1.61 + DCHECK(max_time >= TimeDelta::FromMicroseconds(0)); 1.62 + // Be careful here. TimeDelta has a precision of microseconds, but this API 1.63 + // is in milliseconds. If there are 5.5ms left, should the delay be 5 or 6? 1.64 + // It should be 6 to avoid returning too early. 1.65 + double timeout = ceil(max_time.InMillisecondsF()); 1.66 + DWORD result = WaitForSingleObject(handle_, static_cast<DWORD>(timeout)); 1.67 + switch (result) { 1.68 + case WAIT_OBJECT_0: 1.69 + return true; 1.70 + case WAIT_TIMEOUT: 1.71 + return false; 1.72 + } 1.73 + // It is most unexpected that this should ever fail. Help consumers learn 1.74 + // about it if it should ever fail. 1.75 + NOTREACHED() << "WaitForSingleObject failed"; 1.76 + return false; 1.77 +} 1.78 + 1.79 +// static 1.80 +size_t WaitableEvent::WaitMany(WaitableEvent** events, size_t count) { 1.81 + HANDLE handles[MAXIMUM_WAIT_OBJECTS]; 1.82 + CHECK(count <= MAXIMUM_WAIT_OBJECTS) 1.83 + << "Can only wait on " << MAXIMUM_WAIT_OBJECTS << " with WaitMany"; 1.84 + 1.85 + for (size_t i = 0; i < count; ++i) 1.86 + handles[i] = events[i]->handle(); 1.87 + 1.88 + DWORD result = 1.89 + WaitForMultipleObjects(count, handles, 1.90 + FALSE, // don't wait for all the objects 1.91 + INFINITE); // no timeout 1.92 + if (result < WAIT_OBJECT_0 || result >= WAIT_OBJECT_0 + count) { 1.93 + NOTREACHED() << "WaitForMultipleObjects failed: " << GetLastError(); 1.94 + return 0; 1.95 + } 1.96 + 1.97 + return result - WAIT_OBJECT_0; 1.98 +} 1.99 + 1.100 +} // namespace base