• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

ibrcommon/ibrcommon/thread/Conditional.cpp

Go to the documentation of this file.
00001 #include "ibrcommon/config.h"
00002 #include "ibrcommon/thread/Conditional.h"
00003 #include "ibrcommon/thread/Thread.h"
00004 #include <sys/time.h>
00005 #include <unistd.h>
00006 #include <cassert>
00007 #include <pthread.h>
00008 
00009 namespace ibrcommon
00010 {
00011         Conditional::Conditional() : Mutex(MUTEX_NORMAL), _abort(false)
00012         {
00013                 pthread_cond_init(&cond, &attr.attr);
00014         }
00015 
00016         Conditional::~Conditional()
00017         {
00018                 pthread_cond_destroy(&cond);
00019         }
00020 
00021         bool Conditional::isLocked()
00022         {
00023                 try {
00024                         trylock();
00025                         leave();
00026                         return false;
00027                 } catch (const ibrcommon::MutexException&) {
00028                         return true;
00029                 }
00030         }
00031 
00032         void Conditional::signal (bool broadcast)
00033         {
00034                 // assert a locked Conditional
00035                 assert(isLocked());
00036 
00037                 int ret = 0;
00038 
00039                 if (broadcast)
00040                         ret = pthread_cond_broadcast( &cond );
00041                 else
00042                         ret = pthread_cond_signal( &cond );
00043         }
00044 
00045         void Conditional::wait(size_t timeout) throw (ConditionalAbortException)
00046         {
00047                 // assert a locked Conditional
00048                 assert(isLocked());
00049 
00050                 if (_abort) throw ConditionalAbortException(ConditionalAbortException::COND_ABORT);
00051 
00052                 if (timeout == 0)
00053                 {
00054                         pthread_cond_wait( &cond, &m_mutex );
00055                         if (_abort) throw ConditionalAbortException(ConditionalAbortException::COND_ABORT);
00056                 }
00057                 else
00058                 {
00059                         struct timespec ts;
00060                         gettimeout(timeout, &ts);
00061                         wait(&ts);
00062                         if (_abort) throw ConditionalAbortException(ConditionalAbortException::COND_ABORT);
00063                 }
00064         }
00065 
00066         void Conditional::wait(struct timespec *ts) throw (ConditionalAbortException)
00067         {
00068                 // assert a locked Conditional
00069                 assert(isLocked());
00070 
00071                 if (_abort) throw ConditionalAbortException(ConditionalAbortException::COND_ABORT);
00072 
00073                 int ret = pthread_cond_timedwait(&cond, &m_mutex, ts);
00074 
00075                 if(ret == ETIMEDOUT)
00076                 {
00077                         throw ConditionalAbortException(ConditionalAbortException::COND_TIMEOUT, "conditional wait timed out");
00078                 }
00079                 else if (ret != 0)
00080                 {
00081                         throw ConditionalAbortException(ConditionalAbortException::COND_ERROR, "error on locking conditional mutex");
00082                 }
00083 
00084                 if (_abort) throw ConditionalAbortException(ConditionalAbortException::COND_ABORT);
00085         }
00086 
00087         Conditional::attribute Conditional::attr;
00088 
00089         Conditional::attribute::attribute()
00090         {
00091                 pthread_condattr_init(&attr);
00092 
00093         #if _POSIX_TIMERS > 0 && defined(HAVE_PTHREAD_CONDATTR_SETCLOCK)
00094         #if defined(_POSIX_MONOTONIC_CLOCK)
00095                 pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
00096         #else
00097                 pthread_condattr_setclock(&attr, CLOCK_REALTIME);
00098         #endif
00099         #endif
00100         }
00101 
00102         void Conditional::gettimeout(size_t msec, struct timespec *ts)
00103         {
00104         #if defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) && defined(_POSIX_MONOTONIC_CLOCK)
00105                 clock_gettime(CLOCK_MONOTONIC, ts);
00106         #elif _POSIX_TIMERS > 0
00107                 clock_gettime(CLOCK_REALTIME, ts);
00108         #else
00109                 timeval tv;
00110                 ::gettimeofday(&tv, NULL);
00111                 ts->tv_sec = tv.tv_sec;
00112                 ts->tv_nsec = tv.tv_usec * 1000l;
00113         #endif
00114                 ts->tv_sec += msec / 1000;
00115                 ts->tv_nsec += (msec % 1000) * 1000000l;
00116                 while(ts->tv_nsec > 1000000000l) {
00117                         ++ts->tv_sec;
00118                         ts->tv_nsec -= 1000000000l;
00119                 }
00120         }
00121 
00122         void Conditional::abort()
00123         {
00124                 // assert a locked Conditional
00125                 assert(isLocked());
00126 
00127                 signal(true);
00128                 _abort = true;
00129         }
00130 
00131         void Conditional::reset()
00132         {
00133                 _abort = false;
00134         }
00135 }
00136 

Generated on Thu Nov 11 2010 09:49:47 for IBR-DTNSuite by  doxygen 1.7.1