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 // ConditionVariable wraps pthreads condition variable synchronization or, on | 5 // ConditionVariable wraps pthreads condition variable synchronization or, on |
6 // Windows, simulates it. This functionality is very helpful for having | 6 // Windows, simulates it. This functionality is very helpful for having |
7 // several threads wait for an event, as is common with a thread pool managed | 7 // several threads wait for an event, as is common with a thread pool managed |
8 // by a master. The meaning of such an event in the (worker) thread pool | 8 // by a master. The meaning of such an event in the (worker) thread pool |
9 // scenario is that additional tasks are now available for processing. It is | 9 // scenario is that additional tasks are now available for processing. It is |
10 // used in Chrome in the DNS prefetching system to notify worker threads that | 10 // used in Chrome in the DNS prefetching system to notify worker threads that |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
61 // | 61 // |
62 // For a discussion of the many very subtle implementation details, see the FAQ | 62 // For a discussion of the many very subtle implementation details, see the FAQ |
63 // at the end of condition_variable_win.cc. | 63 // at the end of condition_variable_win.cc. |
64 | 64 |
65 #ifndef BASE_SYNCHRONIZATION_CONDITION_VARIABLE_H_ | 65 #ifndef BASE_SYNCHRONIZATION_CONDITION_VARIABLE_H_ |
66 #define BASE_SYNCHRONIZATION_CONDITION_VARIABLE_H_ | 66 #define BASE_SYNCHRONIZATION_CONDITION_VARIABLE_H_ |
67 #pragma once | 67 #pragma once |
68 | 68 |
69 #include "build/build_config.h" | 69 #include "build/build_config.h" |
70 | 70 |
71 #if defined(OS_WIN) | 71 #if defined(OS_POSIX) |
72 #include <windows.h> | |
73 #elif defined(OS_POSIX) | |
74 #include <pthread.h> | 72 #include <pthread.h> |
75 #endif | 73 #endif |
76 | 74 |
77 #include "base/base_export.h" | 75 #include "base/base_export.h" |
78 #include "base/basictypes.h" | 76 #include "base/basictypes.h" |
79 #include "base/synchronization/lock.h" | 77 #include "base/synchronization/lock.h" |
80 | 78 |
81 namespace base { | 79 namespace base { |
82 | 80 |
| 81 class ConditionVarImpl; |
83 class TimeDelta; | 82 class TimeDelta; |
84 | 83 |
85 class BASE_EXPORT ConditionVariable { | 84 class BASE_EXPORT ConditionVariable { |
86 public: | 85 public: |
87 // Construct a cv for use with ONLY one user lock. | 86 // Construct a cv for use with ONLY one user lock. |
88 explicit ConditionVariable(Lock* user_lock); | 87 explicit ConditionVariable(Lock* user_lock); |
89 | 88 |
90 ~ConditionVariable(); | 89 ~ConditionVariable(); |
91 | 90 |
92 // Wait() releases the caller's critical section atomically as it starts to | 91 // Wait() releases the caller's critical section atomically as it starts to |
93 // sleep, and the reacquires it when it is signaled. | 92 // sleep, and the reacquires it when it is signaled. |
94 void Wait(); | 93 void Wait(); |
95 void TimedWait(const TimeDelta& max_time); | 94 void TimedWait(const TimeDelta& max_time); |
96 | 95 |
97 // Broadcast() revives all waiting threads. | 96 // Broadcast() revives all waiting threads. |
98 void Broadcast(); | 97 void Broadcast(); |
99 // Signal() revives one waiting thread. | 98 // Signal() revives one waiting thread. |
100 void Signal(); | 99 void Signal(); |
101 | 100 |
102 private: | 101 private: |
103 | 102 |
104 #if defined(OS_WIN) | 103 #if defined(OS_WIN) |
105 | 104 ConditionVarImpl* impl_; |
106 // Define Event class that is used to form circularly linked lists. | |
107 // The list container is an element with NULL as its handle_ value. | |
108 // The actual list elements have a non-zero handle_ value. | |
109 // All calls to methods MUST be done under protection of a lock so that links | |
110 // can be validated. Without the lock, some links might asynchronously | |
111 // change, and the assertions would fail (as would list change operations). | |
112 class Event { | |
113 public: | |
114 // Default constructor with no arguments creates a list container. | |
115 Event(); | |
116 ~Event(); | |
117 | |
118 // InitListElement transitions an instance from a container, to an element. | |
119 void InitListElement(); | |
120 | |
121 // Methods for use on lists. | |
122 bool IsEmpty() const; | |
123 void PushBack(Event* other); | |
124 Event* PopFront(); | |
125 Event* PopBack(); | |
126 | |
127 // Methods for use on list elements. | |
128 // Accessor method. | |
129 HANDLE handle() const; | |
130 // Pull an element from a list (if it's in one). | |
131 Event* Extract(); | |
132 | |
133 // Method for use on a list element or on a list. | |
134 bool IsSingleton() const; | |
135 | |
136 private: | |
137 // Provide pre/post conditions to validate correct manipulations. | |
138 bool ValidateAsDistinct(Event* other) const; | |
139 bool ValidateAsItem() const; | |
140 bool ValidateAsList() const; | |
141 bool ValidateLinks() const; | |
142 | |
143 HANDLE handle_; | |
144 Event* next_; | |
145 Event* prev_; | |
146 DISALLOW_COPY_AND_ASSIGN(Event); | |
147 }; | |
148 | |
149 // Note that RUNNING is an unlikely number to have in RAM by accident. | |
150 // This helps with defensive destructor coding in the face of user error. | |
151 enum RunState { SHUTDOWN = 0, RUNNING = 64213 }; | |
152 | |
153 // Internal implementation methods supporting Wait(). | |
154 Event* GetEventForWaiting(); | |
155 void RecycleEvent(Event* used_event); | |
156 | |
157 RunState run_state_; | |
158 | |
159 // Private critical section for access to member data. | |
160 base::Lock internal_lock_; | |
161 | |
162 // Lock that is acquired before calling Wait(). | |
163 base::Lock& user_lock_; | |
164 | |
165 // Events that threads are blocked on. | |
166 Event waiting_list_; | |
167 | |
168 // Free list for old events. | |
169 Event recycling_list_; | |
170 int recycling_list_size_; | |
171 | |
172 // The number of allocated, but not yet deleted events. | |
173 int allocation_counter_; | |
174 | |
175 #elif defined(OS_POSIX) | 105 #elif defined(OS_POSIX) |
176 | |
177 pthread_cond_t condition_; | 106 pthread_cond_t condition_; |
178 pthread_mutex_t* user_mutex_; | 107 pthread_mutex_t* user_mutex_; |
179 #if !defined(NDEBUG) | 108 #if !defined(NDEBUG) |
180 base::Lock* user_lock_; // Needed to adjust shadow lock state on wait. | 109 base::Lock* user_lock_; // Needed to adjust shadow lock state on wait. |
181 #endif | 110 #endif |
182 | 111 |
183 #endif | 112 #endif |
184 | 113 |
185 DISALLOW_COPY_AND_ASSIGN(ConditionVariable); | 114 DISALLOW_COPY_AND_ASSIGN(ConditionVariable); |
186 }; | 115 }; |
187 | 116 |
188 } // namespace base | 117 } // namespace base |
189 | 118 |
190 #endif // BASE_SYNCHRONIZATION_CONDITION_VARIABLE_H_ | 119 #endif // BASE_SYNCHRONIZATION_CONDITION_VARIABLE_H_ |
OLD | NEW |