LCOV - code coverage report
Current view: top level - lunchbox - condition.cpp (source / functions) Hit Total Coverage
Test: Lunchbox Lines: 47 59 79.7 %
Date: 2016-11-11 05:21:33 Functions: 10 10 100.0 %

          Line data    Source code
       1             : 
       2             : /* Copyright (c) 2010-2015, Stefan Eilemann <eile@eyescale.ch>
       3             :  *
       4             :  * This library is free software; you can redistribute it and/or modify it under
       5             :  * the terms of the GNU Lesser General Public License version 2.1 as published
       6             :  * by the Free Software Foundation.
       7             :  *
       8             :  * This library is distributed in the hope that it will be useful, but WITHOUT
       9             :  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
      10             :  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
      11             :  * details.
      12             :  *
      13             :  * You should have received a copy of the GNU Lesser General Public License
      14             :  * along with this library; if not, write to the Free Software Foundation, Inc.,
      15             :  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      16             :  */
      17             : 
      18             : #include "condition.h"
      19             : #include "debug.h"
      20             : #include "time.h"
      21             : 
      22             : #include <cstring>
      23             : #include <errno.h>
      24             : 
      25             : #ifdef _WIN32
      26             : #  include "condition_w32.ipp"
      27             : #else
      28             : #  include <pthread.h>
      29             : #  include <sys/time.h>
      30             : #endif
      31             : 
      32             : namespace lunchbox
      33             : {
      34             : namespace detail
      35             : {
      36             : class Condition
      37             : {
      38             : public:
      39             :     pthread_mutex_t mutex;
      40             :     pthread_cond_t  cond;
      41             : };
      42             : }
      43             : 
      44        1652 : Condition::Condition()
      45        1652 :         : _impl( new detail::Condition )
      46             : {
      47             :     // mutex init
      48        1652 :     int error = pthread_mutex_init( &_impl->mutex, 0 );
      49        1652 :     if( error )
      50             :     {
      51           0 :         LBERROR << "Error creating pthread mutex: " << strerror( error )
      52           0 :                 << std::endl;
      53           0 :         return;
      54             :     }
      55             : 
      56             :     // condvar init
      57        1652 :     error = pthread_cond_init( &_impl->cond, 0 );
      58        1652 :     if( error )
      59             :     {
      60           0 :         LBERROR << "Error creating pthread condition: " << strerror( error )
      61           0 :                 << std::endl;
      62           0 :         return;
      63             :     }
      64             : }
      65             : 
      66        3304 : Condition::~Condition()
      67             : {
      68        1652 :     int error = pthread_mutex_destroy( &_impl->mutex );
      69        1652 :     if( error )
      70           0 :         LBERROR << "Error destroying pthread mutex: " << strerror( error )
      71           0 :                 << " at " << backtrace << std::endl;
      72             : 
      73        1652 :     error = pthread_cond_destroy( &_impl->cond );
      74        1652 :     if( error )
      75           0 :         LBERROR << "Error destroying pthread condition: " << strerror( error )
      76           0 :                 << std::endl;
      77             : 
      78        1652 :     delete _impl;
      79        1652 : }
      80             : 
      81     5689667 : void Condition::lock()
      82             : {
      83     5689667 :     pthread_mutex_lock( &_impl->mutex );
      84     5707628 : }
      85             : 
      86      200016 : void Condition::signal()
      87             : {
      88      200016 :     pthread_cond_signal( &_impl->cond );
      89      200016 : }
      90             : 
      91     4834640 : void Condition::broadcast()
      92             : {
      93     4834640 :     pthread_cond_broadcast( &_impl->cond );
      94     4834640 : }
      95             : 
      96     5707628 : void Condition::unlock()
      97             : {
      98     5707628 :     pthread_mutex_unlock( &_impl->mutex );
      99     5701617 : }
     100             : 
     101      635176 : void Condition::wait()
     102             : {
     103      635176 :     pthread_cond_wait( &_impl->cond, &_impl->mutex );
     104      635176 : }
     105             : 
     106      145225 : bool Condition::timedWait( const uint32_t timeout )
     107             : {
     108      145225 :     if( timeout == LB_TIMEOUT_INDEFINITE )
     109             :     {
     110           4 :         wait();
     111           4 :         return true;
     112             :     }
     113             : 
     114      145221 :     const uint32_t time = timeout == LB_TIMEOUT_DEFAULT ?
     115      145221 :         300000 /* 5 min */ : timeout;
     116             : 
     117             : #ifdef _WIN32
     118             :     int error = pthread_cond_timedwait_w32_np( &_impl->cond, &_impl->mutex,
     119             :                                                time );
     120             : #else
     121      145221 :     const timespec delta = convertToTimespec( time );
     122             :     timeval now;
     123      145221 :     gettimeofday( &now, 0 );
     124             : 
     125             :     timespec then;
     126      145221 :     then.tv_sec  = delta.tv_sec + now.tv_sec;
     127      145221 :     then.tv_nsec = delta.tv_nsec + now.tv_usec * 1000;
     128      145389 :     while( then.tv_nsec > 1000000000 )
     129             :     {
     130          84 :         ++then.tv_sec;
     131          84 :         then.tv_nsec -= 1000000000;
     132             :     }
     133             : 
     134      145221 :     int error = pthread_cond_timedwait( &_impl->cond, &_impl->mutex, &then );
     135             : #endif
     136      145221 :     if( error == ETIMEDOUT )
     137          34 :         return false;
     138             : 
     139      145187 :     if( error )
     140           0 :         LBERROR << "pthread_cond_timedwait failed: " << strerror( error )
     141           0 :                 << std::endl;
     142      145187 :     return true;
     143             : }
     144             : 
     145          72 : }

Generated by: LCOV version 1.11