1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/ipc/chromium/src/base/condition_variable_posix.cc Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,88 @@ 1.4 +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1.5 +// Use of this source code is governed by a BSD-style license that can be 1.6 +// found in the LICENSE file. 1.7 + 1.8 +#include "base/condition_variable.h" 1.9 + 1.10 +#include <errno.h> 1.11 +#include <sys/time.h> 1.12 + 1.13 +#include "base/lock.h" 1.14 +#include "base/lock_impl.h" 1.15 +#include "base/logging.h" 1.16 +#include "base/time.h" 1.17 + 1.18 +using base::Time; 1.19 +using base::TimeDelta; 1.20 + 1.21 +ConditionVariable::ConditionVariable(Lock* user_lock) 1.22 + : user_mutex_(user_lock->lock_impl()->os_lock()) { 1.23 + int rv = 0; 1.24 +#if !defined(OS_MACOSX) && !defined(OS_ANDROID) 1.25 + pthread_condattr_t attrs; 1.26 + rv = pthread_condattr_init(&attrs); 1.27 + DCHECK_EQ(0, rv); 1.28 + pthread_condattr_setclock(&attrs, CLOCK_MONOTONIC); 1.29 + rv = pthread_cond_init(&condition_, &attrs); 1.30 + pthread_condattr_destroy(&attrs); 1.31 +#else 1.32 + rv = pthread_cond_init(&condition_, NULL); 1.33 +#endif 1.34 + DCHECK_EQ(0, rv); 1.35 +} 1.36 + 1.37 +ConditionVariable::~ConditionVariable() { 1.38 + int rv = pthread_cond_destroy(&condition_); 1.39 + DCHECK(rv == 0); 1.40 +} 1.41 + 1.42 +void ConditionVariable::Wait() { 1.43 + int rv = pthread_cond_wait(&condition_, user_mutex_); 1.44 + DCHECK(rv == 0); 1.45 +} 1.46 + 1.47 +void ConditionVariable::TimedWait(const TimeDelta& max_time) { 1.48 + int64_t usecs = max_time.InMicroseconds(); 1.49 + 1.50 + struct timespec relative_time; 1.51 + relative_time.tv_sec = usecs / Time::kMicrosecondsPerSecond; 1.52 + relative_time.tv_nsec = 1.53 + (usecs % Time::kMicrosecondsPerSecond) * Time::kNanosecondsPerMicrosecond; 1.54 + 1.55 +#if defined(OS_MACOSX) 1.56 + int rv = pthread_cond_timedwait_relative_np( 1.57 + &condition_, user_mutex_, &relative_time); 1.58 +#else 1.59 + // The timeout argument to pthread_cond_timedwait is in absolute time. 1.60 + struct timespec now; 1.61 + clock_gettime(CLOCK_MONOTONIC, &now); 1.62 + 1.63 + struct timespec absolute_time; 1.64 + absolute_time.tv_sec = now.tv_sec; 1.65 + absolute_time.tv_nsec = now.tv_nsec; 1.66 + absolute_time.tv_sec += relative_time.tv_sec; 1.67 + absolute_time.tv_nsec += relative_time.tv_nsec; 1.68 + absolute_time.tv_sec += absolute_time.tv_nsec / Time::kNanosecondsPerSecond; 1.69 + absolute_time.tv_nsec %= Time::kNanosecondsPerSecond; 1.70 + DCHECK_GE(absolute_time.tv_sec, now.tv_sec); // Overflow paranoia 1.71 + 1.72 +#if defined(OS_ANDROID) 1.73 + int rv = pthread_cond_timedwait_monotonic_np( 1.74 + &condition_, user_mutex_, &absolute_time); 1.75 +#else 1.76 + int rv = pthread_cond_timedwait(&condition_, user_mutex_, &absolute_time); 1.77 +#endif // OS_ANDROID 1.78 +#endif // OS_MACOSX 1.79 + 1.80 + DCHECK(rv == 0 || rv == ETIMEDOUT); 1.81 +} 1.82 + 1.83 +void ConditionVariable::Broadcast() { 1.84 + int rv = pthread_cond_broadcast(&condition_); 1.85 + DCHECK(rv == 0); 1.86 +} 1.87 + 1.88 +void ConditionVariable::Signal() { 1.89 + int rv = pthread_cond_signal(&condition_); 1.90 + DCHECK(rv == 0); 1.91 +}