diff options
Diffstat (limited to 'ipc/chromium/src/base/condition_variable_posix.cc')
-rw-r--r-- | ipc/chromium/src/base/condition_variable_posix.cc | 50 |
1 files changed, 30 insertions, 20 deletions
diff --git a/ipc/chromium/src/base/condition_variable_posix.cc b/ipc/chromium/src/base/condition_variable_posix.cc index 4a8024c2bc..8b689f5e5d 100644 --- a/ipc/chromium/src/base/condition_variable_posix.cc +++ b/ipc/chromium/src/base/condition_variable_posix.cc @@ -1,23 +1,19 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "base/condition_variable.h" #include <errno.h> +#include <stdint.h> #include <sys/time.h> #include "base/lock.h" -#include "base/lock_impl.h" -#include "base/logging.h" #include "base/time.h" - -using base::Time; -using base::TimeDelta; +#include "build/build_config.h" ConditionVariable::ConditionVariable(Lock* user_lock) - : user_mutex_(user_lock->lock_impl()->os_lock()) { + : user_mutex_(user_lock->lock_.native_handle()) { int rv = 0; #if !defined(OS_MACOSX) pthread_condattr_t attrs; @@ -33,52 +29,66 @@ ConditionVariable::ConditionVariable(Lock* user_lock) } ConditionVariable::~ConditionVariable() { +#if defined(OS_MACOSX) + // This hack is necessary to avoid a fatal pthreads subsystem bug in the + // Darwin kernel. http://crbug.com/517681. + { + Lock lock; + AutoLock l(lock); + struct timespec ts; + ts.tv_sec = 0; + ts.tv_nsec = 1; + pthread_cond_timedwait_relative_np(&condition_, lock.lock_.native_handle(), + &ts); + } +#endif int rv = pthread_cond_destroy(&condition_); - DCHECK(rv == 0); + DCHECK_EQ(0, rv); } void ConditionVariable::Wait() { int rv = pthread_cond_wait(&condition_, user_mutex_); - DCHECK(rv == 0); + DCHECK_EQ(0, rv); } -void ConditionVariable::TimedWait(const TimeDelta& max_time) { +void ConditionVariable::TimedWait(const base::TimeDelta& max_time) { int64_t usecs = max_time.InMicroseconds(); - struct timespec relative_time; - relative_time.tv_sec = usecs / Time::kMicrosecondsPerSecond; + relative_time.tv_sec = usecs / base::Time::kMicrosecondsPerSecond; relative_time.tv_nsec = - (usecs % Time::kMicrosecondsPerSecond) * Time::kNanosecondsPerMicrosecond; + (usecs % base::Time::kMicrosecondsPerSecond) * base::Time::kNanosecondsPerMicrosecond; #if defined(OS_MACOSX) int rv = pthread_cond_timedwait_relative_np( &condition_, user_mutex_, &relative_time); #else // The timeout argument to pthread_cond_timedwait is in absolute time. + struct timespec absolute_time; struct timespec now; clock_gettime(CLOCK_MONOTONIC, &now); - - struct timespec absolute_time; absolute_time.tv_sec = now.tv_sec; absolute_time.tv_nsec = now.tv_nsec; absolute_time.tv_sec += relative_time.tv_sec; absolute_time.tv_nsec += relative_time.tv_nsec; - absolute_time.tv_sec += absolute_time.tv_nsec / Time::kNanosecondsPerSecond; - absolute_time.tv_nsec %= Time::kNanosecondsPerSecond; + absolute_time.tv_sec += absolute_time.tv_nsec / base::Time::kNanosecondsPerSecond; + absolute_time.tv_nsec %= base::Time::kNanosecondsPerSecond; DCHECK_GE(absolute_time.tv_sec, now.tv_sec); // Overflow paranoia int rv = pthread_cond_timedwait(&condition_, user_mutex_, &absolute_time); #endif // OS_MACOSX + + // On failure, we only expect the CV to timeout. Any other error value means + // that we've unexpectedly woken up. DCHECK(rv == 0 || rv == ETIMEDOUT); } void ConditionVariable::Broadcast() { int rv = pthread_cond_broadcast(&condition_); - DCHECK(rv == 0); + DCHECK_EQ(0, rv); } void ConditionVariable::Signal() { int rv = pthread_cond_signal(&condition_); - DCHECK(rv == 0); + DCHECK_EQ(0, rv); } |