Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:38:31

0001 //////////////////////////////////////////////////////////////////////////////
0002 //
0003 // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
0004 // Software License, Version 1.0. (See accompanying file
0005 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 // See http://www.boost.org/libs/interprocess for documentation.
0008 //
0009 //////////////////////////////////////////////////////////////////////////////
0010 
0011 #ifndef BOOST_INTERPROCESS_POSIX_SEMAPHORE_WRAPPER_HPP
0012 #define BOOST_INTERPROCESS_POSIX_SEMAPHORE_WRAPPER_HPP
0013 
0014 #ifndef BOOST_CONFIG_HPP
0015 #  include <boost/config.hpp>
0016 #endif
0017 #
0018 #if defined(BOOST_HAS_PRAGMA_ONCE)
0019 #  pragma once
0020 #endif
0021 
0022 #include <boost/interprocess/exceptions.hpp>
0023 #include <boost/interprocess/creation_tags.hpp>
0024 #include <boost/interprocess/detail/os_file_functions.hpp>
0025 #include <boost/interprocess/detail/shared_dir_helpers.hpp>
0026 #include <boost/interprocess/detail/timed_utils.hpp>
0027 #include <boost/interprocess/permissions.hpp>
0028 
0029 #include <fcntl.h>      //O_CREAT, O_*...
0030 #include <unistd.h>     //close
0031 #include <string>       //std::string
0032 #include <semaphore.h>  //sem_* family, SEM_VALUE_MAX
0033 #include <sys/stat.h>   //mode_t, S_IRWXG, S_IRWXO, S_IRWXU,
0034 #include <boost/assert.hpp>
0035 
0036 #ifdef SEM_FAILED
0037 #define BOOST_INTERPROCESS_POSIX_SEM_FAILED (reinterpret_cast<sem_t*>(SEM_FAILED))
0038 #else
0039 #define BOOST_INTERPROCESS_POSIX_SEM_FAILED (reinterpret_cast<sem_t*>(-1))
0040 #endif
0041 
0042 #ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
0043 #include <boost/interprocess/sync/posix/timepoint_to_timespec.hpp>
0044 #else
0045 #include <boost/interprocess/detail/os_thread_functions.hpp>
0046 #include <boost/interprocess/sync/detail/locks.hpp>
0047 #include <boost/interprocess/sync/detail/common_algorithms.hpp>
0048 #endif
0049 
0050 namespace boost {
0051 namespace interprocess {
0052 namespace ipcdetail {
0053 
0054 #ifdef BOOST_INTERPROCESS_POSIX_NAMED_SEMAPHORES
0055 
0056 inline bool semaphore_open
0057    (sem_t *&handle, create_enum_t type, const char *origname,
0058     unsigned int count = 0, const permissions &perm = permissions())
0059 {
0060    std::string name;
0061    #ifndef BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_SEMAPHORES
0062    add_leading_slash(origname, name);
0063    #else
0064    create_shared_dir_cleaning_old_and_get_filepath(origname, name);
0065    #endif
0066 
0067    //Create new mapping
0068    int oflag = 0;
0069    switch(type){
0070       case DoOpen:
0071       {
0072          //No addition
0073          handle = ::sem_open(name.c_str(), oflag);
0074       }
0075       break;
0076       case DoOpenOrCreate:
0077       case DoCreate:
0078       {
0079          while(1){
0080             oflag = (O_CREAT | O_EXCL);
0081             handle = ::sem_open(name.c_str(), oflag, perm.get_permissions(), count);
0082             if(handle != BOOST_INTERPROCESS_POSIX_SEM_FAILED){
0083                //We can't change semaphore permissions!
0084                //::fchmod(handle, perm.get_permissions());
0085                break;
0086             }
0087             else if(errno == EEXIST && type == DoOpenOrCreate){
0088                oflag = 0;
0089                if( (handle = ::sem_open(name.c_str(), oflag)) != BOOST_INTERPROCESS_POSIX_SEM_FAILED
0090                    || (errno != ENOENT) ){
0091                   break;
0092                }
0093             }
0094             else{
0095                break;
0096             }
0097          }
0098       }
0099       break;
0100       default:
0101       {
0102          error_info err(other_error);
0103          throw interprocess_exception(err);
0104       }
0105    }
0106 
0107    //Check for error
0108    if(handle == BOOST_INTERPROCESS_POSIX_SEM_FAILED){
0109       throw interprocess_exception(error_info(errno));
0110    }
0111 
0112    return true;
0113 }
0114 
0115 inline void semaphore_close(sem_t *handle)
0116 {
0117    int ret = sem_close(handle);
0118    if(ret != 0){
0119       BOOST_ASSERT(0);
0120    }
0121 }
0122 
0123 inline bool semaphore_unlink(const char *semname)
0124 {
0125    BOOST_TRY{
0126       std::string sem_str;
0127       #ifndef BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_SEMAPHORES
0128       add_leading_slash(semname, sem_str);
0129       #else
0130       shared_filepath(semname, sem_str);
0131       #endif
0132       return 0 == sem_unlink(sem_str.c_str());
0133    }
0134    BOOST_CATCH(...){
0135       return false;
0136    } BOOST_CATCH_END
0137 }
0138 
0139 #endif   //BOOST_INTERPROCESS_POSIX_NAMED_SEMAPHORES
0140 
0141 #ifdef BOOST_INTERPROCESS_POSIX_UNNAMED_SEMAPHORES
0142 
0143 inline void semaphore_init(sem_t *handle, unsigned int initialCount)
0144 {
0145    int ret = sem_init(handle, 1, initialCount);
0146    //According to SUSV3 version 2003 edition, the return value of a successful
0147    //sem_init call is not defined, but -1 is returned on failure.
0148    //In the future, a successful call might be required to return 0.
0149    if(ret == -1){
0150       error_info err = system_error_code();
0151       throw interprocess_exception(err);
0152    }
0153 }
0154 
0155 inline void semaphore_destroy(sem_t *handle)
0156 {
0157    int ret = sem_destroy(handle);
0158    if(ret != 0){
0159       BOOST_ASSERT(0);
0160    }
0161 }
0162 
0163 #endif   //BOOST_INTERPROCESS_POSIX_UNNAMED_SEMAPHORES
0164 
0165 inline void semaphore_post(sem_t *handle)
0166 {
0167    int ret = sem_post(handle);
0168    if(ret != 0){
0169       error_info err = system_error_code();
0170       throw interprocess_exception(err);
0171    }
0172 }
0173 
0174 inline void semaphore_wait(sem_t *handle)
0175 {
0176    int ret = sem_wait(handle);
0177    if(ret != 0){
0178       error_info err = system_error_code();
0179       throw interprocess_exception(err);
0180    }
0181 }
0182 
0183 inline bool semaphore_try_wait(sem_t *handle)
0184 {
0185    int res = sem_trywait(handle);
0186    if(res == 0)
0187       return true;
0188    if(system_error_code() == EAGAIN){
0189       return false;
0190    }
0191    error_info err = system_error_code();
0192    throw interprocess_exception(err);
0193 }
0194 
0195 #ifndef BOOST_INTERPROCESS_POSIX_TIMEOUTS
0196 
0197 struct semaphore_wrapper_try_wrapper
0198 {
0199    explicit semaphore_wrapper_try_wrapper(sem_t *handle)
0200       : m_handle(handle)
0201    {}
0202 
0203    void wait()
0204    {  semaphore_wait(m_handle);  }
0205 
0206    bool try_wait()
0207    {  return semaphore_try_wait(m_handle);  }
0208 
0209    private:
0210    sem_t *m_handle;
0211 };
0212 
0213 #endif
0214 
0215 template<class TimePoint>
0216 inline bool semaphore_timed_wait(sem_t *handle, const TimePoint &abs_time)
0217 {
0218    #ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
0219    //Posix does not support infinity absolute time so handle it here
0220    if(ipcdetail::is_pos_infinity(abs_time)){
0221       semaphore_wait(handle);
0222       return true;
0223    }
0224 
0225    timespec tspec = timepoint_to_timespec(abs_time);
0226    for (;;){
0227       int res = sem_timedwait(handle, &tspec);
0228       if(res == 0)
0229          return true;
0230       if (res > 0){
0231          //buggy glibc, copy the returned error code to errno
0232          errno = res;
0233       }
0234       if(system_error_code() == ETIMEDOUT){
0235          return false;
0236       }
0237       error_info err = system_error_code();
0238       throw interprocess_exception(err);
0239    }
0240    return false;
0241    #else //#ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
0242 
0243    semaphore_wrapper_try_wrapper swtw(handle);
0244    ipcdetail::lock_to_wait<semaphore_wrapper_try_wrapper> lw(swtw);
0245    return ipcdetail::try_based_timed_lock(lw, abs_time);
0246 
0247    #endif   //#ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
0248 }
0249 
0250 }  //namespace ipcdetail {
0251 }  //namespace interprocess {
0252 }  //namespace boost {
0253 
0254 #endif   //#ifndef BOOST_INTERPROCESS_POSIX_SEMAPHORE_WRAPPER_HPP