Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(401)

Side by Side Diff: base/synchronization/waitable_event_win.cc

Issue 1980743002: Track thread activities in order to diagnose hangs. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@readwrite-mmf
Patch Set: more clean-up and addressed review comments Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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 diagonsis).
manzagop (departed) 2016/06/16 15:19:41 typo: diagonsis, here an below.
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 diagonsis).
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 // Record the event that this thread is blocking upon (for hang diagonsis).
manzagop (departed) 2016/06/16 15:19:41 Put a note that this is looking at the first event
bcwhite 2016/06/16 17:04:43 Done.
88 base::debug::ScopedEventWaitActivity event_activity(events[0]);
manzagop (departed) 2016/06/16 15:19:41 Can count be 0?
bcwhite 2016/06/16 17:04:43 Done.
89
80 base::ThreadRestrictions::AssertWaitAllowed(); 90 base::ThreadRestrictions::AssertWaitAllowed();
81 HANDLE handles[MAXIMUM_WAIT_OBJECTS]; 91 HANDLE handles[MAXIMUM_WAIT_OBJECTS];
82 CHECK_LE(count, static_cast<size_t>(MAXIMUM_WAIT_OBJECTS)) 92 CHECK_LE(count, static_cast<size_t>(MAXIMUM_WAIT_OBJECTS))
83 << "Can only wait on " << MAXIMUM_WAIT_OBJECTS << " with WaitMany"; 93 << "Can only wait on " << MAXIMUM_WAIT_OBJECTS << " with WaitMany";
84 94
85 for (size_t i = 0; i < count; ++i) 95 for (size_t i = 0; i < count; ++i)
86 handles[i] = events[i]->handle(); 96 handles[i] = events[i]->handle();
87 97
88 // The cast is safe because count is small - see the CHECK above. 98 // The cast is safe because count is small - see the CHECK above.
89 DWORD result = 99 DWORD result =
90 WaitForMultipleObjects(static_cast<DWORD>(count), 100 WaitForMultipleObjects(static_cast<DWORD>(count),
91 handles, 101 handles,
92 FALSE, // don't wait for all the objects 102 FALSE, // don't wait for all the objects
93 INFINITE); // no timeout 103 INFINITE); // no timeout
94 if (result >= WAIT_OBJECT_0 + count) { 104 if (result >= WAIT_OBJECT_0 + count) {
95 DPLOG(FATAL) << "WaitForMultipleObjects failed"; 105 DPLOG(FATAL) << "WaitForMultipleObjects failed";
96 return 0; 106 return 0;
97 } 107 }
98 108
99 return result - WAIT_OBJECT_0; 109 return result - WAIT_OBJECT_0;
100 } 110 }
101 111
102 } // namespace base 112 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698