Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/condition_variable.h"
7 #include <errno.h>
8 #include <sys/time.h>
10 #include "base/lock.h"
11 #include "base/lock_impl.h"
12 #include "base/logging.h"
13 #include "base/time.h"
15 using base::Time;
16 using base::TimeDelta;
18 ConditionVariable::ConditionVariable(Lock* user_lock)
19 : user_mutex_(user_lock->lock_impl()->os_lock()) {
20 int rv = 0;
21 #if !defined(OS_MACOSX) && !defined(OS_ANDROID)
22 pthread_condattr_t attrs;
23 rv = pthread_condattr_init(&attrs);
24 DCHECK_EQ(0, rv);
25 pthread_condattr_setclock(&attrs, CLOCK_MONOTONIC);
26 rv = pthread_cond_init(&condition_, &attrs);
27 pthread_condattr_destroy(&attrs);
28 #else
29 rv = pthread_cond_init(&condition_, NULL);
30 #endif
31 DCHECK_EQ(0, rv);
32 }
34 ConditionVariable::~ConditionVariable() {
35 int rv = pthread_cond_destroy(&condition_);
36 DCHECK(rv == 0);
37 }
39 void ConditionVariable::Wait() {
40 int rv = pthread_cond_wait(&condition_, user_mutex_);
41 DCHECK(rv == 0);
42 }
44 void ConditionVariable::TimedWait(const TimeDelta& max_time) {
45 int64_t usecs = max_time.InMicroseconds();
47 struct timespec relative_time;
48 relative_time.tv_sec = usecs / Time::kMicrosecondsPerSecond;
49 relative_time.tv_nsec =
50 (usecs % Time::kMicrosecondsPerSecond) * Time::kNanosecondsPerMicrosecond;
52 #if defined(OS_MACOSX)
53 int rv = pthread_cond_timedwait_relative_np(
54 &condition_, user_mutex_, &relative_time);
55 #else
56 // The timeout argument to pthread_cond_timedwait is in absolute time.
57 struct timespec now;
58 clock_gettime(CLOCK_MONOTONIC, &now);
60 struct timespec absolute_time;
61 absolute_time.tv_sec = now.tv_sec;
62 absolute_time.tv_nsec = now.tv_nsec;
63 absolute_time.tv_sec += relative_time.tv_sec;
64 absolute_time.tv_nsec += relative_time.tv_nsec;
65 absolute_time.tv_sec += absolute_time.tv_nsec / Time::kNanosecondsPerSecond;
66 absolute_time.tv_nsec %= Time::kNanosecondsPerSecond;
67 DCHECK_GE(absolute_time.tv_sec, now.tv_sec); // Overflow paranoia
69 #if defined(OS_ANDROID)
70 int rv = pthread_cond_timedwait_monotonic_np(
71 &condition_, user_mutex_, &absolute_time);
72 #else
73 int rv = pthread_cond_timedwait(&condition_, user_mutex_, &absolute_time);
74 #endif // OS_ANDROID
75 #endif // OS_MACOSX
77 DCHECK(rv == 0 || rv == ETIMEDOUT);
78 }
80 void ConditionVariable::Broadcast() {
81 int rv = pthread_cond_broadcast(&condition_);
82 DCHECK(rv == 0);
83 }
85 void ConditionVariable::Signal() {
86 int rv = pthread_cond_signal(&condition_);
87 DCHECK(rv == 0);
88 }