Semaphore.H
Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 #ifndef UTIL_SEMAPHORE_H_DEFINED
00039 #define UTIL_SEMAPHORE_H_DEFINED
00040 
00041 #include "Util/log.H"
00042 
00043 #include <cerrno>
00044 #include <pthread.h>
00045 #include <semaphore.h> 
00046 
00047 class PosixSemaphore;
00048 class CondVarSemaphore;
00049 
00050 #ifdef HAVE_WORKING_POSIX_SEMAPHORES
00051 typedef PosixSemaphore Semaphore;
00052 #else
00053 typedef CondVarSemaphore Semaphore;
00054 #endif
00055 
00056 
00057 class PosixSemaphore
00058 {
00059 public:
00060   PosixSemaphore(unsigned int initvalue = 0)
00061   {
00062     if (0 != sem_init(&itsSem, 0, initvalue))
00063       PLFATAL("sem_init() failed");
00064   }
00065 
00066   ~PosixSemaphore()
00067   {
00068     if (0 != sem_destroy(&itsSem))
00069       PLERROR("sem_destroy() failed");
00070   }
00071 
00072 
00073   bool post()
00074   {
00075     if (0 != sem_post(&itsSem))
00076       {
00077         
00078         
00079         PLERROR("sem_post() failed");
00080         return false;
00081       }
00082     return true;
00083   }
00084 
00085   
00086   bool trywait()
00087   {
00088     errno = 0;
00089     if(0 == sem_trywait(&itsSem))
00090       return true;
00091     else
00092       {
00093         if(errno == EAGAIN)
00094           {
00095             errno = 0;
00096           }
00097         else
00098           {
00099             PLERROR("sem_trywait() failed");
00100           }
00101         return false;
00102       }
00103   }
00104 
00105 
00106   bool wait()
00107   {
00108     errno = 0;
00109     while (0 != sem_wait(&itsSem))
00110       {
00111         if (errno == EINTR)
00112           {
00113             PLERROR("sem_wait() failed; retrying... ");
00114             continue;
00115           }
00116         else
00117           {
00118             PLERROR("sem_wait() failed");
00119             return false;
00120           }
00121       }
00122     return true;
00123   }
00124 
00125 private:
00126   PosixSemaphore(const PosixSemaphore&); 
00127   PosixSemaphore& operator=(const PosixSemaphore&); 
00128 
00129   sem_t itsSem;
00130 };
00131 
00132 class CondVarSemaphore
00133 {
00134 public:
00135   CondVarSemaphore(unsigned int initvalue = 0)
00136     :
00137     itsCounter(initvalue)
00138   {
00139     if (0 != pthread_mutex_init(&itsMutex, NULL))
00140       PLFATAL("pthread_mutex_init() failed");
00141 
00142     if (0 != pthread_cond_init(&itsCond, NULL))
00143       PLFATAL("pthread_cond_init() failed");
00144   }
00145 
00146   ~CondVarSemaphore()
00147   {
00148     if (0 != pthread_cond_destroy(&itsCond))
00149       PLERROR("pthread_cond_destroy() failed");
00150 
00151     if (0 != pthread_mutex_destroy(&itsMutex))
00152       PLERROR("pthread_mutex_destroy() failed");
00153   }
00154 
00155   bool post()
00156   {
00157     bool retval = true;
00158 
00159     if (0 != pthread_mutex_lock(&itsMutex)) retval = false;
00160     ++itsCounter;
00161     if (0 != pthread_cond_signal(&itsCond)) retval = false;
00162     if (0 != pthread_mutex_unlock(&itsMutex)) retval = false;
00163 
00164     return retval;
00165   }
00166 
00167   bool trywait()
00168   {
00169     bool retval = true;
00170     if (0 != pthread_mutex_lock(&itsMutex)) retval = false;
00171     
00172     if (itsCounter > 0)
00173       --itsCounter;
00174     
00175     if (0 != pthread_mutex_unlock(&itsMutex)) retval = false;
00176     return retval;
00177   }
00178   
00179   bool wait()
00180   {
00181     bool retval = true;
00182 
00183     if (0 != pthread_mutex_lock(&itsMutex)) retval = false;
00184 
00185     while (itsCounter == 0)
00186       if (0 != pthread_cond_wait(&itsCond, &itsMutex)) retval = false;
00187 
00188     --itsCounter;
00189 
00190     if (0 != pthread_mutex_unlock(&itsMutex)) retval = false;
00191 
00192     return retval;
00193   }
00194 
00195 private:
00196   CondVarSemaphore(const CondVarSemaphore&); 
00197   CondVarSemaphore& operator=(const CondVarSemaphore&); 
00198 
00199   volatile unsigned int itsCounter;
00200   pthread_cond_t itsCond;
00201   pthread_mutex_t itsMutex;
00202 };
00203 
00204 
00205 
00206 
00207 
00208 
00209 
00210 
00211 #endif // UTIL_SEMAPHORE_H_DEFINED