annotate DEPENDENCIES/generic/include/boost/interprocess/sync/posix/semaphore_wrapper.hpp @ 16:2665513ce2d3

Add boost headers
author Chris Cannam
date Tue, 05 Aug 2014 11:11:38 +0100
parents
children c530137014c0
rev   line source
Chris@16 1 //////////////////////////////////////////////////////////////////////////////
Chris@16 2 //
Chris@16 3 // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
Chris@16 4 // Software License, Version 1.0. (See accompanying file
Chris@16 5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@16 6 //
Chris@16 7 // See http://www.boost.org/libs/interprocess for documentation.
Chris@16 8 //
Chris@16 9 //////////////////////////////////////////////////////////////////////////////
Chris@16 10
Chris@16 11 #ifndef BOOST_INTERPROCESS_POSIX_SEMAPHORE_WRAPPER_HPP
Chris@16 12 #define BOOST_INTERPROCESS_POSIX_SEMAPHORE_WRAPPER_HPP
Chris@16 13
Chris@16 14 #include <boost/interprocess/detail/posix_time_types_wrk.hpp>
Chris@16 15 #include <boost/interprocess/exceptions.hpp>
Chris@16 16 #include <boost/interprocess/creation_tags.hpp>
Chris@16 17 #include <boost/interprocess/detail/os_file_functions.hpp>
Chris@16 18 #include <boost/interprocess/detail/tmp_dir_helpers.hpp>
Chris@16 19 #include <boost/interprocess/permissions.hpp>
Chris@16 20
Chris@16 21 #include <fcntl.h> //O_CREAT, O_*...
Chris@16 22 #include <unistd.h> //close
Chris@16 23 #include <string> //std::string
Chris@16 24 #include <semaphore.h> //sem_* family, SEM_VALUE_MAX
Chris@16 25 #include <sys/stat.h> //mode_t, S_IRWXG, S_IRWXO, S_IRWXU,
Chris@16 26 #include <boost/assert.hpp>
Chris@16 27
Chris@16 28 #ifdef SEM_FAILED
Chris@16 29 #define BOOST_INTERPROCESS_POSIX_SEM_FAILED (reinterpret_cast<sem_t*>(SEM_FAILED))
Chris@16 30 #else
Chris@16 31 #define BOOST_INTERPROCESS_POSIX_SEM_FAILED (reinterpret_cast<sem_t*>(-1))
Chris@16 32 #endif
Chris@16 33
Chris@16 34 #ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
Chris@16 35 #include <boost/interprocess/sync/posix/ptime_to_timespec.hpp>
Chris@16 36 #else
Chris@16 37 #include <boost/interprocess/detail/os_thread_functions.hpp>
Chris@16 38 #include <boost/interprocess/sync/spin/wait.hpp>
Chris@16 39 #endif
Chris@16 40
Chris@16 41 namespace boost {
Chris@16 42 namespace interprocess {
Chris@16 43 namespace ipcdetail {
Chris@16 44
Chris@16 45 inline bool semaphore_open
Chris@16 46 (sem_t *&handle, create_enum_t type, const char *origname,
Chris@16 47 unsigned int count = 0, const permissions &perm = permissions())
Chris@16 48 {
Chris@16 49 std::string name;
Chris@16 50 #ifndef BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_SEMAPHORES
Chris@16 51 add_leading_slash(origname, name);
Chris@16 52 #else
Chris@16 53 create_tmp_and_clean_old_and_get_filename(origname, name);
Chris@16 54 #endif
Chris@16 55
Chris@16 56 //Create new mapping
Chris@16 57 int oflag = 0;
Chris@16 58 switch(type){
Chris@16 59 case DoOpen:
Chris@16 60 {
Chris@16 61 //No addition
Chris@16 62 handle = ::sem_open(name.c_str(), oflag);
Chris@16 63 }
Chris@16 64 break;
Chris@16 65 case DoOpenOrCreate:
Chris@16 66 case DoCreate:
Chris@16 67 {
Chris@16 68 while(1){
Chris@16 69 oflag = (O_CREAT | O_EXCL);
Chris@16 70 handle = ::sem_open(name.c_str(), oflag, perm.get_permissions(), count);
Chris@16 71 if(handle != BOOST_INTERPROCESS_POSIX_SEM_FAILED){
Chris@16 72 //We can't change semaphore permissions!
Chris@16 73 //::fchmod(handle, perm.get_permissions());
Chris@16 74 break;
Chris@16 75 }
Chris@16 76 else if(errno == EEXIST && type == DoOpenOrCreate){
Chris@16 77 oflag = 0;
Chris@16 78 if( (handle = ::sem_open(name.c_str(), oflag)) != BOOST_INTERPROCESS_POSIX_SEM_FAILED
Chris@16 79 || (errno != ENOENT) ){
Chris@16 80 break;
Chris@16 81 }
Chris@16 82 }
Chris@16 83 else{
Chris@16 84 break;
Chris@16 85 }
Chris@16 86 }
Chris@16 87 }
Chris@16 88 break;
Chris@16 89 default:
Chris@16 90 {
Chris@16 91 error_info err(other_error);
Chris@16 92 throw interprocess_exception(err);
Chris@16 93 }
Chris@16 94 }
Chris@16 95
Chris@16 96 //Check for error
Chris@16 97 if(handle == BOOST_INTERPROCESS_POSIX_SEM_FAILED){
Chris@16 98 throw interprocess_exception(error_info(errno));
Chris@16 99 }
Chris@16 100
Chris@16 101 return true;
Chris@16 102 }
Chris@16 103
Chris@16 104 inline void semaphore_close(sem_t *handle)
Chris@16 105 {
Chris@16 106 int ret = sem_close(handle);
Chris@16 107 if(ret != 0){
Chris@16 108 BOOST_ASSERT(0);
Chris@16 109 }
Chris@16 110 }
Chris@16 111
Chris@16 112 inline bool semaphore_unlink(const char *semname)
Chris@16 113 {
Chris@16 114 try{
Chris@16 115 std::string sem_str;
Chris@16 116 #ifndef BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_SEMAPHORES
Chris@16 117 add_leading_slash(semname, sem_str);
Chris@16 118 #else
Chris@16 119 tmp_filename(semname, sem_str);
Chris@16 120 #endif
Chris@16 121 return 0 == sem_unlink(sem_str.c_str());
Chris@16 122 }
Chris@16 123 catch(...){
Chris@16 124 return false;
Chris@16 125 }
Chris@16 126 }
Chris@16 127
Chris@16 128 inline void semaphore_init(sem_t *handle, unsigned int initialCount)
Chris@16 129 {
Chris@16 130 int ret = sem_init(handle, 1, initialCount);
Chris@16 131 //According to SUSV3 version 2003 edition, the return value of a successful
Chris@16 132 //sem_init call is not defined, but -1 is returned on failure.
Chris@16 133 //In the future, a successful call might be required to return 0.
Chris@16 134 if(ret == -1){
Chris@16 135 throw interprocess_exception(system_error_code());
Chris@16 136 }
Chris@16 137 }
Chris@16 138
Chris@16 139 inline void semaphore_destroy(sem_t *handle)
Chris@16 140 {
Chris@16 141 int ret = sem_destroy(handle);
Chris@16 142 if(ret != 0){
Chris@16 143 BOOST_ASSERT(0);
Chris@16 144 }
Chris@16 145 }
Chris@16 146
Chris@16 147 inline void semaphore_post(sem_t *handle)
Chris@16 148 {
Chris@16 149 int ret = sem_post(handle);
Chris@16 150 if(ret != 0){
Chris@16 151 throw interprocess_exception(system_error_code());
Chris@16 152 }
Chris@16 153 }
Chris@16 154
Chris@16 155 inline void semaphore_wait(sem_t *handle)
Chris@16 156 {
Chris@16 157 int ret = sem_wait(handle);
Chris@16 158 if(ret != 0){
Chris@16 159 throw interprocess_exception(system_error_code());
Chris@16 160 }
Chris@16 161 }
Chris@16 162
Chris@16 163 inline bool semaphore_try_wait(sem_t *handle)
Chris@16 164 {
Chris@16 165 int res = sem_trywait(handle);
Chris@16 166 if(res == 0)
Chris@16 167 return true;
Chris@16 168 if(system_error_code() == EAGAIN){
Chris@16 169 return false;
Chris@16 170 }
Chris@16 171 throw interprocess_exception(system_error_code());
Chris@16 172 return false;
Chris@16 173 }
Chris@16 174
Chris@16 175 inline bool semaphore_timed_wait(sem_t *handle, const boost::posix_time::ptime &abs_time)
Chris@16 176 {
Chris@16 177 if(abs_time == boost::posix_time::pos_infin){
Chris@16 178 semaphore_wait(handle);
Chris@16 179 return true;
Chris@16 180 }
Chris@16 181 #ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
Chris@16 182 timespec tspec = ptime_to_timespec(abs_time);
Chris@16 183 for (;;){
Chris@16 184 int res = sem_timedwait(handle, &tspec);
Chris@16 185 if(res == 0)
Chris@16 186 return true;
Chris@16 187 if (res > 0){
Chris@16 188 //buggy glibc, copy the returned error code to errno
Chris@16 189 errno = res;
Chris@16 190 }
Chris@16 191 if(system_error_code() == ETIMEDOUT){
Chris@16 192 return false;
Chris@16 193 }
Chris@16 194 throw interprocess_exception(system_error_code());
Chris@16 195 }
Chris@16 196 return false;
Chris@16 197 #else //#ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
Chris@16 198 boost::posix_time::ptime now;
Chris@16 199 spin_wait swait;
Chris@16 200 do{
Chris@16 201 if(semaphore_try_wait(handle))
Chris@16 202 return true;
Chris@16 203 swait.yield();
Chris@16 204 }while((now = microsec_clock::universal_time()) < abs_time);
Chris@16 205 return false;
Chris@16 206 #endif //#ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
Chris@16 207 }
Chris@16 208
Chris@16 209 } //namespace ipcdetail {
Chris@16 210 } //namespace interprocess {
Chris@16 211 } //namespace boost {
Chris@16 212
Chris@16 213 #endif //#ifndef BOOST_INTERPROCESS_POSIX_SEMAPHORE_WRAPPER_HPP