| OLD | NEW | 
|    1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |    1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 
|    2 // Use of this source code is governed by a BSD-style license that can be |    2 // Use of this source code is governed by a BSD-style license that can be | 
|    3 // found in the LICENSE file. |    3 // found in the LICENSE file. | 
|    4  |    4  | 
|    5 #include "base/synchronization/waitable_event.h" |    5 #include "base/synchronization/waitable_event.h" | 
|    6  |    6  | 
|    7 #include <windows.h> |    7 #include <windows.h> | 
|    8 #include <stddef.h> |    8 #include <stddef.h> | 
|    9  |    9  | 
|   10 #include <utility> |   10 #include <utility> | 
|   11  |   11  | 
 |   12 #include "base/debug/activity_tracker.h" | 
|   12 #include "base/logging.h" |   13 #include "base/logging.h" | 
|   13 #include "base/numerics/safe_conversions.h" |   14 #include "base/numerics/safe_conversions.h" | 
|   14 #include "base/threading/thread_restrictions.h" |   15 #include "base/threading/thread_restrictions.h" | 
|   15 #include "base/time/time.h" |   16 #include "base/time/time.h" | 
|   16  |   17  | 
|   17 namespace base { |   18 namespace base { | 
|   18  |   19  | 
|   19 WaitableEvent::WaitableEvent(ResetPolicy reset_policy, |   20 WaitableEvent::WaitableEvent(ResetPolicy reset_policy, | 
|   20                              InitialState initial_state) |   21                              InitialState initial_state) | 
|   21     : handle_(CreateEvent(nullptr, |   22     : handle_(CreateEvent(nullptr, | 
| (...skipping 18 matching lines...) Expand all  Loading... | 
|   40  |   41  | 
|   41 void WaitableEvent::Signal() { |   42 void WaitableEvent::Signal() { | 
|   42   SetEvent(handle_.Get()); |   43   SetEvent(handle_.Get()); | 
|   43 } |   44 } | 
|   44  |   45  | 
|   45 bool WaitableEvent::IsSignaled() { |   46 bool WaitableEvent::IsSignaled() { | 
|   46   return TimedWait(TimeDelta()); |   47   return TimedWait(TimeDelta()); | 
|   47 } |   48 } | 
|   48  |   49  | 
|   49 void WaitableEvent::Wait() { |   50 void WaitableEvent::Wait() { | 
 |   51   // Record the event that this thread is blocking upon (for hang diagnosis). | 
 |   52   base::debug::ScopedEventWaitActivity event_activity(this); | 
 |   53  | 
|   50   base::ThreadRestrictions::AssertWaitAllowed(); |   54   base::ThreadRestrictions::AssertWaitAllowed(); | 
|   51   DWORD result = WaitForSingleObject(handle_.Get(), INFINITE); |   55   DWORD result = WaitForSingleObject(handle_.Get(), INFINITE); | 
|   52   // It is most unexpected that this should ever fail.  Help consumers learn |   56   // It is most unexpected that this should ever fail.  Help consumers learn | 
|   53   // about it if it should ever fail. |   57   // about it if it should ever fail. | 
|   54   DCHECK_EQ(WAIT_OBJECT_0, result) << "WaitForSingleObject failed"; |   58   DCHECK_EQ(WAIT_OBJECT_0, result) << "WaitForSingleObject failed"; | 
|   55 } |   59 } | 
|   56  |   60  | 
|   57 bool WaitableEvent::TimedWait(const TimeDelta& max_time) { |   61 bool WaitableEvent::TimedWait(const TimeDelta& max_time) { | 
 |   62   // Record the event that this thread is blocking upon (for hang diagnosis). | 
 |   63   base::debug::ScopedEventWaitActivity event_activity(this); | 
 |   64  | 
|   58   base::ThreadRestrictions::AssertWaitAllowed(); |   65   base::ThreadRestrictions::AssertWaitAllowed(); | 
|   59   DCHECK_GE(max_time, TimeDelta()); |   66   DCHECK_GE(max_time, TimeDelta()); | 
|   60   // Truncate the timeout to milliseconds. The API specifies that this method |   67   // Truncate the timeout to milliseconds. The API specifies that this method | 
|   61   // can return in less than |max_time| (when returning false), as the argument |   68   // can return in less than |max_time| (when returning false), as the argument | 
|   62   // is the maximum time that a caller is willing to wait. |   69   // is the maximum time that a caller is willing to wait. | 
|   63   DWORD timeout = saturated_cast<DWORD>(max_time.InMilliseconds()); |   70   DWORD timeout = saturated_cast<DWORD>(max_time.InMilliseconds()); | 
|   64  |   71  | 
|   65   DWORD result = WaitForSingleObject(handle_.Get(), timeout); |   72   DWORD result = WaitForSingleObject(handle_.Get(), timeout); | 
|   66   switch (result) { |   73   switch (result) { | 
|   67     case WAIT_OBJECT_0: |   74     case WAIT_OBJECT_0: | 
|   68       return true; |   75       return true; | 
|   69     case WAIT_TIMEOUT: |   76     case WAIT_TIMEOUT: | 
|   70       return false; |   77       return false; | 
|   71   } |   78   } | 
|   72   // It is most unexpected that this should ever fail.  Help consumers learn |   79   // It is most unexpected that this should ever fail.  Help consumers learn | 
|   73   // about it if it should ever fail. |   80   // about it if it should ever fail. | 
|   74   NOTREACHED() << "WaitForSingleObject failed"; |   81   NOTREACHED() << "WaitForSingleObject failed"; | 
|   75   return false; |   82   return false; | 
|   76 } |   83 } | 
|   77  |   84  | 
|   78 // static |   85 // static | 
|   79 size_t WaitableEvent::WaitMany(WaitableEvent** events, size_t count) { |   86 size_t WaitableEvent::WaitMany(WaitableEvent** events, size_t count) { | 
 |   87   DCHECK(count) << "Cannot wait on no events"; | 
 |   88  | 
 |   89   // Record an event (the first) that this thread is blocking upon. | 
 |   90   base::debug::ScopedEventWaitActivity event_activity(events[0]); | 
 |   91  | 
|   80   base::ThreadRestrictions::AssertWaitAllowed(); |   92   base::ThreadRestrictions::AssertWaitAllowed(); | 
|   81   HANDLE handles[MAXIMUM_WAIT_OBJECTS]; |   93   HANDLE handles[MAXIMUM_WAIT_OBJECTS]; | 
|   82   CHECK_LE(count, static_cast<size_t>(MAXIMUM_WAIT_OBJECTS)) |   94   CHECK_LE(count, static_cast<size_t>(MAXIMUM_WAIT_OBJECTS)) | 
|   83       << "Can only wait on " << MAXIMUM_WAIT_OBJECTS << " with WaitMany"; |   95       << "Can only wait on " << MAXIMUM_WAIT_OBJECTS << " with WaitMany"; | 
|   84  |   96  | 
|   85   for (size_t i = 0; i < count; ++i) |   97   for (size_t i = 0; i < count; ++i) | 
|   86     handles[i] = events[i]->handle(); |   98     handles[i] = events[i]->handle(); | 
|   87  |   99  | 
|   88   // The cast is safe because count is small - see the CHECK above. |  100   // The cast is safe because count is small - see the CHECK above. | 
|   89   DWORD result = |  101   DWORD result = | 
|   90       WaitForMultipleObjects(static_cast<DWORD>(count), |  102       WaitForMultipleObjects(static_cast<DWORD>(count), | 
|   91                              handles, |  103                              handles, | 
|   92                              FALSE,      // don't wait for all the objects |  104                              FALSE,      // don't wait for all the objects | 
|   93                              INFINITE);  // no timeout |  105                              INFINITE);  // no timeout | 
|   94   if (result >= WAIT_OBJECT_0 + count) { |  106   if (result >= WAIT_OBJECT_0 + count) { | 
|   95     DPLOG(FATAL) << "WaitForMultipleObjects failed"; |  107     DPLOG(FATAL) << "WaitForMultipleObjects failed"; | 
|   96     return 0; |  108     return 0; | 
|   97   } |  109   } | 
|   98  |  110  | 
|   99   return result - WAIT_OBJECT_0; |  111   return result - WAIT_OBJECT_0; | 
|  100 } |  112 } | 
|  101  |  113  | 
|  102 }  // namespace base |  114 }  // namespace base | 
| OLD | NEW |