| 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 |