diff options
author | mmentovai@google.com <mmentovai@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-08-08 16:19:43 +0000 |
---|---|---|
committer | mmentovai@google.com <mmentovai@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-08-08 16:19:43 +0000 |
commit | 08048c71997f7ec047f20fb0132db3884bada97d (patch) | |
tree | ea1aa92547415c6597ad15b37590887cb28a2316 /base/condition_variable.h | |
parent | 7fc9f719bfd04c02539cab7ca5da4fdc3eda588e (diff) | |
download | chromium_src-08048c71997f7ec047f20fb0132db3884bada97d.zip chromium_src-08048c71997f7ec047f20fb0132db3884bada97d.tar.gz chromium_src-08048c71997f7ec047f20fb0132db3884bada97d.tar.bz2 |
Port LockImpl, Lock, and ConditionVariable to pthreads-supporting platforms.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@567 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/condition_variable.h')
-rw-r--r-- | base/condition_variable.h | 77 |
1 files changed, 40 insertions, 37 deletions
diff --git a/base/condition_variable.h b/base/condition_variable.h index bdb9a19..f30ffba 100644 --- a/base/condition_variable.h +++ b/base/condition_variable.h @@ -27,37 +27,35 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// ConditionVariable is a reasonable attempt at simulating -// the newer Posix and Vista-only construct for condition variable -// synchronization. This functionality is very helpful for having several -// threads wait for an event, as is common with a thread pool -// managed by a master. The meaning of such an event in the -// (worker) thread pool scenario is that additional tasks are -// now available for processing. It is used in Chrome in the -// DNS prefetching system to notify worker threads that a queue -// now has items (tasks) which need to be tended to. -// A related use would have a pool manager waiting on a -// ConditionVariable, waiting for a thread in the pool to announce -// (signal) that there is now more room in a (bounded size) communications -// queue for the manager to deposit tasks, or, as a second example, that -// the queue of tasks is completely empty and all workers are waiting. - +// ConditionVariable wraps pthreads condition variable synchronization or, on +// Windows, simulates it. This functionality is very helpful for having +// several threads wait for an event, as is common with a thread pool managed +// by a master. The meaning of such an event in the (worker) thread pool +// scenario is that additional tasks are now available for processing. It is +// used in Chrome in the DNS prefetching system to notify worker threads that +// a queue now has items (tasks) which need to be tended to. A related use +// would have a pool manager waiting on a ConditionVariable, waiting for a +// thread in the pool to announce (signal) that there is now more room in a +// (bounded size) communications queue for the manager to deposit tasks, or, +// as a second example, that the queue of tasks is completely empty and all +// workers are waiting. +// // USAGE NOTE 1: spurious signal events are possible with this and // most implementations of condition variables. As a result, be // *sure* to retest your condition before proceeding. The following // is a good example of doing this correctly: - +// // while (!work_to_be_done()) Wait(...); - +// // In contrast do NOT do the following: - +// // if (!work_to_be_done()) Wait(...); // Don't do this. - +// // Especially avoid the above if you are relying on some other thread only // issuing a signal up *if* there is work-to-do. There can/will // be spurious signals. Recheck state on waiting thread before // assuming the signal was intentional. Caveat caller ;-). - +// // USAGE NOTE 2: Broadcast() frees up all waiting threads at once, // which leads to contention for the locks they all held when they // called Wait(). This results in POOR performance. A much better @@ -65,11 +63,11 @@ // thread (upon exiting Wait()) call Signal() to free up another // Wait'ing thread. Look at condition_variable_unittest.cc for // both examples. - +// // Broadcast() can be used nicely during teardown, as it gets the job // done, and leaves no sleeping threads... and performance is less // critical at that point. - +// // The semantics of Broadcast() are carefully crafted so that *all* // threads that were waiting when the request was made will indeed // get signaled. Some implementations mess up, and don't signal them @@ -77,7 +75,7 @@ // for a while while waiting threads come around). This implementation // appears correct, as it will not "lose" any signals, and will guarantee // that all threads get signaled by Broadcast(). - +// // This implementation offers support for "performance" in its selection of // which thread to revive. Performance, in direct contrast with "fairness," // assures that the thread that most recently began to Wait() is selected by @@ -85,20 +83,18 @@ // thread that has Wait()ed the longest is selected. The default policy // may improve performance, as the selected thread may have a greater chance of // having some of its stack data in various CPU caches. - +// // For a discussion of the many very subtle implementation details, see the FAQ -// at the end of condition_variable.cc. +// at the end of condition_variable_win.cc. -#ifndef BASE_CONDITION_VARIABLE_H__ -#define BASE_CONDITION_VARIABLE_H__ +#ifndef BASE_CONDITION_VARIABLE_H_ +#define BASE_CONDITION_VARIABLE_H_ #include "base/lock.h" #include "base/logging.h" #include "base/scoped_ptr.h" #include "base/time.h" -class Lock; - class ConditionVariable { public: // Construct a cv for use with ONLY one user lock. @@ -108,12 +104,8 @@ class ConditionVariable { // Wait() releases the caller's critical section atomically as it starts to // sleep, and the reacquires it when it is signaled. + void Wait(); void TimedWait(const TimeDelta& max_time); - void Wait() { - // Default to "wait forever" timing, which means have to get a Signal() - // or Broadcast() to come out of this wait state. - TimedWait(TimeDelta::FromMilliseconds(INFINITE)); - } // Broadcast() revives all waiting threads. void Broadcast(); @@ -121,6 +113,9 @@ class ConditionVariable { void Signal(); private: + +#if defined(OS_WIN) + // Define Event class that is used to form circularly linked lists. // The list container is an element with NULL as its handle_ value. // The actual list elements have a non-zero handle_ value. @@ -161,7 +156,7 @@ class ConditionVariable { HANDLE handle_; Event* next_; Event* prev_; - DISALLOW_EVIL_CONSTRUCTORS(Event); + DISALLOW_COPY_AND_ASSIGN(Event); }; // Note that RUNNING is an unlikely number to have in RAM by accident. @@ -176,6 +171,7 @@ class ConditionVariable { // Private critical section for access to member data. Lock internal_lock_; + // Lock that is acquired before calling Wait(). Lock& user_lock_; @@ -189,7 +185,14 @@ class ConditionVariable { // The number of allocated, but not yet deleted events. int allocation_counter_; - DISALLOW_EVIL_CONSTRUCTORS(ConditionVariable); +#elif defined(OS_POSIX) + + pthread_cond_t condition_; + pthread_mutex_t* user_mutex_; + +#endif + + DISALLOW_COPY_AND_ASSIGN(ConditionVariable); }; -#endif // BASE_CONDITION_VARIABLE_H__ +#endif // BASE_CONDITION_VARIABLE_H_ |