tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

waitable_event_win.cc (2723B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
      4 // Use of this source code is governed by a BSD-style license that can be
      5 // found in the LICENSE file.
      6 
      7 #include "base/waitable_event.h"
      8 
      9 #include <math.h>
     10 #include <windows.h>
     11 
     12 #include "base/logging.h"
     13 #include "base/time.h"
     14 
     15 namespace base {
     16 
     17 WaitableEvent::WaitableEvent(bool manual_reset, bool signaled)
     18    : handle_(CreateEvent(NULL, manual_reset, signaled, NULL)) {
     19  // We're probably going to crash anyways if this is ever NULL, so we might as
     20  // well make our stack reports more informative by crashing here.
     21  CHECK(handle_);
     22 }
     23 
     24 WaitableEvent::~WaitableEvent() { CloseHandle(handle_); }
     25 
     26 void WaitableEvent::Reset() { ResetEvent(handle_); }
     27 
     28 void WaitableEvent::Signal() { SetEvent(handle_); }
     29 
     30 bool WaitableEvent::IsSignaled() {
     31  return TimedWait(TimeDelta::FromMilliseconds(0));
     32 }
     33 
     34 bool WaitableEvent::Wait() {
     35  DWORD result = WaitForSingleObject(handle_, INFINITE);
     36  // It is most unexpected that this should ever fail.  Help consumers learn
     37  // about it if it should ever fail.
     38  DCHECK(result == WAIT_OBJECT_0) << "WaitForSingleObject failed";
     39  return result == WAIT_OBJECT_0;
     40 }
     41 
     42 bool WaitableEvent::TimedWait(const TimeDelta& max_time) {
     43  DCHECK(max_time >= TimeDelta::FromMicroseconds(0));
     44  // Be careful here.  TimeDelta has a precision of microseconds, but this API
     45  // is in milliseconds.  If there are 5.5ms left, should the delay be 5 or 6?
     46  // It should be 6 to avoid returning too early.
     47  double timeout = ceil(max_time.InMillisecondsF());
     48  DWORD result = WaitForSingleObject(handle_, static_cast<DWORD>(timeout));
     49  switch (result) {
     50    case WAIT_OBJECT_0:
     51      return true;
     52    case WAIT_TIMEOUT:
     53      return false;
     54  }
     55  // It is most unexpected that this should ever fail.  Help consumers learn
     56  // about it if it should ever fail.
     57  NOTREACHED() << "WaitForSingleObject failed";
     58  return false;
     59 }
     60 
     61 // static
     62 size_t WaitableEvent::WaitMany(WaitableEvent** events, size_t count) {
     63  HANDLE handles[MAXIMUM_WAIT_OBJECTS];
     64  CHECK(count <= MAXIMUM_WAIT_OBJECTS)
     65  << "Can only wait on " << MAXIMUM_WAIT_OBJECTS << " with WaitMany";
     66 
     67  for (size_t i = 0; i < count; ++i) handles[i] = events[i]->handle();
     68 
     69  DWORD result =
     70      WaitForMultipleObjects(count, handles,
     71                             FALSE,      // don't wait for all the objects
     72                             INFINITE);  // no timeout
     73  if (result >= WAIT_OBJECT_0 + count) {
     74    NOTREACHED() << "WaitForMultipleObjects failed: " << GetLastError();
     75    return 0;
     76  }
     77 
     78  return result - WAIT_OBJECT_0;
     79 }
     80 
     81 }  // namespace base