semaphore_wrapper.hpp

来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 275 行

HPP
275
字号
////////////////////////////////////////////////////////////////////////////////// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost// Software License, Version 1.0. (See accompanying file// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)//// See http://www.boost.org/libs/interprocess for documentation.////////////////////////////////////////////////////////////////////////////////#ifndef BOOST_INTERPROCESS_POSIX_SEMAPHORE_WRAPPER_HPP#define BOOST_INTERPROCESS_POSIX_SEMAPHORE_WRAPPER_HPP#include <boost/interprocess/detail/posix_time_types_wrk.hpp>#include <boost/interprocess/exceptions.hpp>#include <boost/interprocess/creation_tags.hpp>#include <boost/interprocess/detail/os_file_functions.hpp>#include <boost/interprocess/detail/tmp_dir_helpers.hpp>#include <string>#include <semaphore.h>#ifdef SEM_FAILED#define BOOST_INTERPROCESS_POSIX_SEM_FAILED SEM_FAILED#else#define BOOST_INTERPROCESS_POSIX_SEM_FAILED (reinterpret_cast<sem_t*>(-1))#endif#ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS#include <boost/interprocess/sync/posix/ptime_to_timespec.hpp>#else#include <boost/interprocess/detail/os_thread_functions.hpp>#endifnamespace boost {namespace interprocess {/// @condnamespace detail{ class interprocess_tester; }/// @endcondnamespace detail {inline bool semaphore_open   (sem_t *&handle, detail::create_enum_t type, const char *origname, mode_t mode,    unsigned int count){   std::string name;   #ifndef BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_SEMAPHORES   detail::add_leading_slash(origname, name);   #else   detail::create_tmp_dir_and_get_filename(origname, name);   #endif   //Create new mapping   int oflag = 0;   if(mode == read_only){      oflag |= O_RDONLY;   }   else if(mode == read_write){      oflag |= O_RDWR;   }   else{      error_info err(mode_error);      throw interprocess_exception(err);   }   switch(type){      case detail::DoOpen:         //No addition      break;      case detail::DoCreate:         oflag |= (O_CREAT | O_EXCL);      break;      case detail::DoOpenOrCreate:         oflag |= O_CREAT;      break;      default:         {            error_info err = other_error;            throw interprocess_exception(err);         }   }   //Open file using POSIX API   if(oflag & O_CREAT)      handle = sem_open(name.c_str(), oflag, S_IRWXO | S_IRWXG | S_IRWXU, count);   else      handle = sem_open(name.c_str(), oflag);   //Check for error   if(handle == BOOST_INTERPROCESS_POSIX_SEM_FAILED){      throw interprocess_exception(error_info(errno));   }   return true;}inline void semaphore_close(sem_t *handle){   int ret = sem_close(handle);   if(ret != 0){        assert(0);   }}inline bool semaphore_unlink(const char *semname){   try{      std::string sem_str;      #ifndef BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_SEMAPHORES      detail::add_leading_slash(semname, sem_str);      #else      detail::tmp_filename(semname, sem_str);      #endif      return 0 != sem_unlink(sem_str.c_str());   }   catch(...){      return false;   }}inline void semaphore_init(sem_t *handle, int initialCount){   int ret = sem_init(handle, 1, initialCount);   //According to SUSV3 version 2003 edition, the return value of a successful   //sem_init call is not defined, but -1 is returned on failure.   //In the future, a successful call might be required to return 0.   if(ret == -1){      throw interprocess_exception(system_error_code());   }}inline void semaphore_destroy(sem_t *handle){   int ret = sem_destroy(handle);   if(ret != 0){        assert(0);   }}inline void semaphore_post(sem_t *handle){   int ret = sem_post(handle);   if(ret != 0){      throw interprocess_exception(system_error_code());   }}inline void semaphore_wait(sem_t *handle){   int ret = sem_wait(handle);   if(ret != 0){      throw interprocess_exception(system_error_code());   }}inline bool semaphore_try_wait(sem_t *handle){   int res = sem_trywait(handle);   if(res == 0)      return true;   if(system_error_code() == EAGAIN){      return false;   }   throw interprocess_exception(system_error_code());   return false;}inline bool semaphore_timed_wait(sem_t *handle, const boost::posix_time::ptime &abs_time){   #ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS   timespec tspec = detail::ptime_to_timespec(abs_time);   for (;;){      int res = sem_timedwait(handle, &tspec);      if(res == 0)         return true;      if (res > 0){         //buggy glibc, copy the returned error code to errno         errno = res;      }      if(system_error_code() == ETIMEDOUT){         return false;      }      throw interprocess_exception(system_error_code());   }   return false;   #else //#ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS   boost::posix_time::ptime now;   while((now = microsec_clock::universal_time()) < abs_time){      if(semaphore_try_wait(handle))         return true;      thread_yield();   }   return false;   #endif   //#ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS}class named_semaphore_wrapper{   named_semaphore_wrapper();   named_semaphore_wrapper(const named_semaphore_wrapper&);   named_semaphore_wrapper &operator= (const named_semaphore_wrapper &);   public:   named_semaphore_wrapper      (detail::create_enum_t type, const char *name, mode_t mode, unsigned int count)   {  semaphore_open(mp_sem, type, name, mode, count);   }   ~named_semaphore_wrapper()   {      if(mp_sem != BOOST_INTERPROCESS_POSIX_SEM_FAILED)         semaphore_close(mp_sem);   }   void post()   {  semaphore_post(mp_sem); }   void wait()   {  semaphore_wait(mp_sem); }   bool try_wait()   {  return semaphore_try_wait(mp_sem); }   bool timed_wait(const boost::posix_time::ptime &abs_time)   {  return semaphore_timed_wait(mp_sem, abs_time); }   static bool remove(const char *name)   {  return semaphore_unlink(name);   }   private:   friend class detail::interprocess_tester;   void dont_close_on_destruction()   {  mp_sem = BOOST_INTERPROCESS_POSIX_SEM_FAILED; }   sem_t      *mp_sem;};class semaphore_wrapper{   semaphore_wrapper();   semaphore_wrapper(const semaphore_wrapper&);   semaphore_wrapper &operator= (const semaphore_wrapper &);   public:   semaphore_wrapper(int initialCount)   {  semaphore_init(&m_sem, initialCount);  }   ~semaphore_wrapper()   {  semaphore_destroy(&m_sem);  }   void post()   {  semaphore_post(&m_sem); }   void wait()   {  semaphore_wait(&m_sem); }   bool try_wait()   {  return semaphore_try_wait(&m_sem); }   bool timed_wait(const boost::posix_time::ptime &abs_time)   {  return semaphore_timed_wait(&m_sem, abs_time); }   private:   sem_t       m_sem;};}  //namespace detail {}  //namespace interprocess {}  //namespace boost {#undef BOOST_INTERPROCESS_POSIX_SEM_FAILED#endif   //#ifndef BOOST_INTERPROCESS_POSIX_SEMAPHORE_WRAPPER_HPP

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?