LCOV - code coverage report
Current view: top level - ipc/chromium/src/base - condition_variable_posix.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 38 42 90.5 %
Date: 2017-07-14 16:53:18 Functions: 5 6 83.3 %
Legend: Lines: hit not hit

          Line data    Source code
       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
       3             : // found in the LICENSE file.
       4             : 
       5             : #include "base/condition_variable.h"
       6             : 
       7             : #include <errno.h>
       8             : #include <stdint.h>
       9             : #include <sys/time.h>
      10             : 
      11             : #include "base/lock.h"
      12             : #include "base/time.h"
      13             : #include "build/build_config.h"
      14             : 
      15         778 : ConditionVariable::ConditionVariable(Lock* user_lock)
      16         778 :     : user_mutex_(user_lock->lock_.native_handle())
      17             : {
      18         780 :   int rv = 0;
      19             :   // http://crbug.com/293736
      20             :   // NaCl doesn't support monotonic clock based absolute deadlines.
      21             :   // On older Android platform versions, it's supported through the
      22             :   // non-standard pthread_cond_timedwait_monotonic_np. Newer platform
      23             :   // versions have pthread_condattr_setclock.
      24             :   // Mac can use relative time deadlines.
      25             : #if !defined(OS_MACOSX) && !defined(OS_NACL) && \
      26             :       !(defined(OS_ANDROID) && defined(HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC))
      27             :   pthread_condattr_t attrs;
      28         780 :   rv = pthread_condattr_init(&attrs);
      29         778 :   DCHECK_EQ(0, rv);
      30         778 :   pthread_condattr_setclock(&attrs, CLOCK_MONOTONIC);
      31         777 :   rv = pthread_cond_init(&condition_, &attrs);
      32         777 :   pthread_condattr_destroy(&attrs);
      33             : #else
      34             :   rv = pthread_cond_init(&condition_, NULL);
      35             : #endif
      36         777 :   DCHECK_EQ(0, rv);
      37         777 : }
      38             : 
      39        1552 : ConditionVariable::~ConditionVariable() {
      40             : #if defined(OS_MACOSX)
      41             :   // This hack is necessary to avoid a fatal pthreads subsystem bug in the
      42             :   // Darwin kernel. http://crbug.com/517681.
      43             :   {
      44             :     Lock lock;
      45             :     AutoLock l(lock);
      46             :     struct timespec ts;
      47             :     ts.tv_sec = 0;
      48             :     ts.tv_nsec = 1;
      49             :     pthread_cond_timedwait_relative_np(&condition_, lock.lock_.native_handle(),
      50             :                                        &ts);
      51             :   }
      52             : #endif
      53             : 
      54         776 :   int rv = pthread_cond_destroy(&condition_);
      55         776 :   DCHECK_EQ(0, rv);
      56         776 : }
      57             : 
      58         254 : void ConditionVariable::Wait() {
      59         254 :   int rv = pthread_cond_wait(&condition_, user_mutex_);
      60         249 :   DCHECK_EQ(0, rv);
      61         249 : }
      62             : 
      63         527 : void ConditionVariable::TimedWait(const base::TimeDelta& max_time) {
      64         527 :   int64_t usecs = max_time.InMicroseconds();
      65             :   struct timespec relative_time;
      66         527 :   relative_time.tv_sec = usecs / base::Time::kMicrosecondsPerSecond;
      67         527 :   relative_time.tv_nsec =
      68         527 :     (usecs % base::Time::kMicrosecondsPerSecond) * base::Time::kNanosecondsPerMicrosecond;
      69             : 
      70             : #if defined(OS_MACOSX)
      71             :   int rv = pthread_cond_timedwait_relative_np(
      72             :       &condition_, user_mutex_, &relative_time);
      73             : #else
      74             :   // The timeout argument to pthread_cond_timedwait is in absolute time.
      75             :   struct timespec absolute_time;
      76             : #if defined(OS_NACL)
      77             :   // See comment in constructor for why this is different in NaCl.
      78             :   struct timeval now;
      79             :   gettimeofday(&now, NULL);
      80             :   absolute_time.tv_sec = now.tv_sec;
      81             :   absolute_time.tv_nsec = now.tv_usec * base::Time::kNanosecondsPerMicrosecond;
      82             : #else
      83             :   struct timespec now;
      84         527 :   clock_gettime(CLOCK_MONOTONIC, &now);
      85         527 :   absolute_time.tv_sec = now.tv_sec;
      86         527 :   absolute_time.tv_nsec = now.tv_nsec;
      87             : #endif
      88             : 
      89         527 :   absolute_time.tv_sec += relative_time.tv_sec;
      90         527 :   absolute_time.tv_nsec += relative_time.tv_nsec;
      91         527 :   absolute_time.tv_sec += absolute_time.tv_nsec / base::Time::kNanosecondsPerSecond;
      92         527 :   absolute_time.tv_nsec %= base::Time::kNanosecondsPerSecond;
      93         527 :   DCHECK_GE(absolute_time.tv_sec, now.tv_sec);  // Overflow paranoia
      94             : 
      95             : #if defined(OS_ANDROID) && defined(HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC)
      96             :   int rv = pthread_cond_timedwait_monotonic_np(
      97             :       &condition_, user_mutex_, &absolute_time);
      98             : #else
      99         527 :   int rv = pthread_cond_timedwait(&condition_, user_mutex_, &absolute_time);
     100             : #endif  // OS_ANDROID && HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC
     101             : #endif  // OS_MACOSX
     102             : 
     103             :   // On failure, we only expect the CV to timeout. Any other error value means
     104             :   // that we've unexpectedly woken up.
     105         527 :   DCHECK(rv == 0 || rv == ETIMEDOUT);
     106         527 : }
     107             : 
     108         253 : void ConditionVariable::Broadcast() {
     109         253 :   int rv = pthread_cond_broadcast(&condition_);
     110         253 :   DCHECK_EQ(0, rv);
     111         253 : }
     112             : 
     113           0 : void ConditionVariable::Signal() {
     114           0 :   int rv = pthread_cond_signal(&condition_);
     115           0 :   DCHECK_EQ(0, rv);
     116           0 : }

Generated by: LCOV version 1.13