Semaphore.H

Go to the documentation of this file.
00001 #ifndef MY_SEMAPHORE_
00002 #define MY_SEMAPHORE_
00003 
00010 extern "C"
00011 {
00012   #include <sys/fcntl.h>
00013   #include <sys/errno.h>
00014   #include <limits.h>
00015 }
00016 
00017 
00018 #ifdef CYGWIN_COMPAT
00019 extern "C"
00020 {
00021   // strange: using "" instead of <> for cygwin
00022   #include "/usr/include/semaphore.h"
00023 }
00024 #else
00025 extern "C"
00026 {
00027   #include <semaphore.h>
00028 }
00029 #endif
00030 
00031 
00033 class CSemaphore_exception : public std::exception
00034 {
00035  private:
00036   const std::string Message;
00037 
00038  public:
00039   explicit CSemaphore_exception(const std::string& Msg) throw()
00040    : Message(Msg)
00041    {
00042 #if defined(VERBOSE) || defined(DEBUG)
00043      cerr << "throwing exception: " << Msg << endl;
00044 #endif
00045    }
00046  
00047   virtual ~CSemaphore_exception() throw() { }
00048   
00049   virtual const char* what() const throw()
00050    {
00051      return Message.c_str();
00052    }  
00053 };
00054 
00055 
00057 class CSemaphore : private ForbidAssignment
00058 {
00059  private:
00060   sem_t resource_counter;
00061  public:
00062   CSemaphore(const unsigned int my_resource_counter)
00063    {
00064      if (my_resource_counter>static_cast<unsigned long int>(SEM_VALUE_MAX))
00065       throw CSemaphore_exception("CSemaphore::constructor: my_resource_counter>SEM_VALUE_MAX");
00066      if (sem_init(&resource_counter, 0, my_resource_counter))
00067       throw CSemaphore_exception("CSemaphore::constructor: initialization failed!");
00068    }
00069   ~CSemaphore()
00070    {
00071      if (sem_destroy(&resource_counter))
00072       throw CSemaphore_exception("CSemaphore::destructor: failed!");
00073    }
00074   void post()
00075    {
00076      if (sem_post(&resource_counter)) throw CSemaphore_exception("CSemaphore_post");
00077    }
00078   void wait()
00079    {
00080      if (sem_wait(&resource_counter)) throw CSemaphore_exception("CSemaphore_wait");
00081    }
00082   bool trywait()
00083    {
00084      int retval=(sem_trywait(&resource_counter));
00085      if (retval==-1 && errno!=EAGAIN) throw CSemaphore_exception("CSemaphore_trywait");
00086      return (retval==0);
00087    }
00088   int getvalue()
00089    {
00090      int retval;
00091      if (sem_getvalue(&resource_counter,&retval)) throw CSemaphore_exception("CSemaphore_getvalue");
00092      return retval;
00093    }
00094 };
00095 
00096 
00098 class CNamedSemaphore : private ForbidAssignment
00099 {
00100  private:
00101   sem_t *p_resource_counter;
00102  public:
00103   CNamedSemaphore(const char *const name, const unsigned int my_resource_counter)
00104    {
00105      if (my_resource_counter>static_cast<unsigned long int>(SEM_VALUE_MAX))
00106       throw CSemaphore_exception("CNamedSemaphore::constructor: my_resource_counter>SEM_VALUE_MAX");
00107      p_resource_counter = sem_open(name, O_CREAT, S_IRWXU|S_IRWXG, my_resource_counter);
00108      if (p_resource_counter == SEM_FAILED)
00109       throw CSemaphore_exception("CNamedSemaphore::constructor: initialization failed!");
00110    }
00111   ~CNamedSemaphore()
00112    {
00113      if (sem_close(p_resource_counter))
00114       throw CSemaphore_exception("CNamedSemaphore::destructor: failed!");
00115    }
00116   void post()
00117    {
00118      if (sem_post(p_resource_counter)) throw CSemaphore_exception("CNamedSemaphore_post");
00119    }
00120   void wait()
00121    {
00122      if (sem_wait(p_resource_counter)) throw CSemaphore_exception("CNamedSemaphore_wait");
00123    }
00124   bool trywait()
00125    {
00126      int retval=(sem_trywait(p_resource_counter));
00127      if (retval==-1 && errno!=EAGAIN) throw CSemaphore_exception("CNamedSemaphore_trywait");
00128      return (retval==0);
00129    }
00130   int getvalue()
00131    {
00132      int retval;
00133      if (sem_getvalue(p_resource_counter,&retval)) throw CSemaphore_exception("CNamedSemaphore_getvalue");
00134      return retval;
00135    }
00136 };
00137 
00138 
00147 class CConditionalNamedSemaphorePostAtDestruction : private ForbidAssignment
00148 {
00149  private:
00150   CNamedSemaphore &Sem;
00151   bool condition;
00152  public:
00153   CConditionalNamedSemaphorePostAtDestruction(CNamedSemaphore &mySem, const bool initial_condition)
00154    : Sem(mySem), condition(initial_condition) { }
00155   ~CConditionalNamedSemaphorePostAtDestruction() { if (condition) Sem.post(); }
00156   void set_condition(const bool new_condition = true) { condition=new_condition; }
00157 };
00158 
00159 
00160 #endif /* MY_SEMAPHORE_ */

Generated on Wed Nov 7 23:29:26 2007 for Qsieve by  doxygen 1.5.4