/Src/Dependencies/Boost/boost/interprocess/sync/posix/semaphore_wrapper.hpp
http://hadesmem.googlecode.com/ · C++ Header · 265 lines · 204 code · 42 blank · 19 comment · 29 complexity · 0338e551e0f436d39408eba78a438651 MD5 · raw file
- //////////////////////////////////////////////////////////////////////////////
- //
- // (C) Copyright Ion Gaztanaga 2005-2009. 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 <boost/interprocess/permissions.hpp>
- #include <string>
- #include <semaphore.h>
- #include <boost/assert.hpp>
- #ifdef SEM_FAILED
- #define BOOST_INTERPROCESS_POSIX_SEM_FAILED (reinterpret_cast<sem_t*>(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>
- #endif
- namespace boost {
- namespace interprocess {
- /// @cond
- namespace detail{ class interprocess_tester; }
- /// @endcond
- namespace detail {
- inline bool semaphore_open
- (sem_t *&handle, detail::create_enum_t type, const char *origname,
- unsigned int count, const permissions &perm = permissions())
- {
- std::string name;
- #ifndef BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_SEMAPHORES
- detail::add_leading_slash(origname, name);
- #else
- detail::create_tmp_and_clean_old_and_get_filename(origname, name);
- #endif
- //Create new mapping
- int oflag = 0;
- 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, perm.get_permissions(), 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){
- BOOST_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, unsigned 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){
- BOOST_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, unsigned int count, const permissions &perm = permissions())
- { semaphore_open(mp_sem, type, name, count, perm); }
- ~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(unsigned 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