annotate DEPENDENCIES/generic/include/boost/interprocess/sync/posix/semaphore_wrapper.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents c530137014c0
children
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@101 14 #ifndef BOOST_CONFIG_HPP
Chris@101 15 # include <boost/config.hpp>
Chris@101 16 #endif
Chris@101 17 #
Chris@101 18 #if defined(BOOST_HAS_PRAGMA_ONCE)
Chris@101 19 # pragma once
Chris@101 20 #endif
Chris@101 21
Chris@16 22 #include <boost/interprocess/detail/posix_time_types_wrk.hpp>
Chris@16 23 #include <boost/interprocess/exceptions.hpp>
Chris@16 24 #include <boost/interprocess/creation_tags.hpp>
Chris@16 25 #include <boost/interprocess/detail/os_file_functions.hpp>
Chris@101 26 #include <boost/interprocess/detail/shared_dir_helpers.hpp>
Chris@16 27 #include <boost/interprocess/permissions.hpp>
Chris@16 28
Chris@16 29 #include <fcntl.h> //O_CREAT, O_*...
Chris@16 30 #include <unistd.h> //close
Chris@16 31 #include <string> //std::string
Chris@16 32 #include <semaphore.h> //sem_* family, SEM_VALUE_MAX
Chris@16 33 #include <sys/stat.h> //mode_t, S_IRWXG, S_IRWXO, S_IRWXU,
Chris@16 34 #include <boost/assert.hpp>
Chris@16 35
Chris@16 36 #ifdef SEM_FAILED
Chris@16 37 #define BOOST_INTERPROCESS_POSIX_SEM_FAILED (reinterpret_cast<sem_t*>(SEM_FAILED))
Chris@16 38 #else
Chris@16 39 #define BOOST_INTERPROCESS_POSIX_SEM_FAILED (reinterpret_cast<sem_t*>(-1))
Chris@16 40 #endif
Chris@16 41
Chris@16 42 #ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
Chris@16 43 #include <boost/interprocess/sync/posix/ptime_to_timespec.hpp>
Chris@16 44 #else
Chris@16 45 #include <boost/interprocess/detail/os_thread_functions.hpp>
Chris@101 46 #include <boost/interprocess/sync/detail/locks.hpp>
Chris@101 47 #include <boost/interprocess/sync/detail/common_algorithms.hpp>
Chris@16 48 #endif
Chris@16 49
Chris@16 50 namespace boost {
Chris@16 51 namespace interprocess {
Chris@16 52 namespace ipcdetail {
Chris@16 53
Chris@101 54 #ifdef BOOST_INTERPROCESS_POSIX_NAMED_SEMAPHORES
Chris@101 55
Chris@16 56 inline bool semaphore_open
Chris@16 57 (sem_t *&handle, create_enum_t type, const char *origname,
Chris@16 58 unsigned int count = 0, const permissions &perm = permissions())
Chris@16 59 {
Chris@16 60 std::string name;
Chris@16 61 #ifndef BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_SEMAPHORES
Chris@16 62 add_leading_slash(origname, name);
Chris@16 63 #else
Chris@101 64 create_shared_dir_cleaning_old_and_get_filepath(origname, name);
Chris@16 65 #endif
Chris@16 66
Chris@16 67 //Create new mapping
Chris@16 68 int oflag = 0;
Chris@16 69 switch(type){
Chris@16 70 case DoOpen:
Chris@16 71 {
Chris@16 72 //No addition
Chris@16 73 handle = ::sem_open(name.c_str(), oflag);
Chris@16 74 }
Chris@16 75 break;
Chris@16 76 case DoOpenOrCreate:
Chris@16 77 case DoCreate:
Chris@16 78 {
Chris@16 79 while(1){
Chris@16 80 oflag = (O_CREAT | O_EXCL);
Chris@16 81 handle = ::sem_open(name.c_str(), oflag, perm.get_permissions(), count);
Chris@16 82 if(handle != BOOST_INTERPROCESS_POSIX_SEM_FAILED){
Chris@16 83 //We can't change semaphore permissions!
Chris@16 84 //::fchmod(handle, perm.get_permissions());
Chris@16 85 break;
Chris@16 86 }
Chris@16 87 else if(errno == EEXIST && type == DoOpenOrCreate){
Chris@16 88 oflag = 0;
Chris@16 89 if( (handle = ::sem_open(name.c_str(), oflag)) != BOOST_INTERPROCESS_POSIX_SEM_FAILED
Chris@16 90 || (errno != ENOENT) ){
Chris@16 91 break;
Chris@16 92 }
Chris@16 93 }
Chris@16 94 else{
Chris@16 95 break;
Chris@16 96 }
Chris@16 97 }
Chris@16 98 }
Chris@16 99 break;
Chris@16 100 default:
Chris@16 101 {
Chris@16 102 error_info err(other_error);
Chris@16 103 throw interprocess_exception(err);
Chris@16 104 }
Chris@16 105 }
Chris@16 106
Chris@16 107 //Check for error
Chris@16 108 if(handle == BOOST_INTERPROCESS_POSIX_SEM_FAILED){
Chris@16 109 throw interprocess_exception(error_info(errno));
Chris@16 110 }
Chris@16 111
Chris@16 112 return true;
Chris@16 113 }
Chris@16 114
Chris@16 115 inline void semaphore_close(sem_t *handle)
Chris@16 116 {
Chris@16 117 int ret = sem_close(handle);
Chris@16 118 if(ret != 0){
Chris@16 119 BOOST_ASSERT(0);
Chris@16 120 }
Chris@16 121 }
Chris@16 122
Chris@16 123 inline bool semaphore_unlink(const char *semname)
Chris@16 124 {
Chris@16 125 try{
Chris@16 126 std::string sem_str;
Chris@16 127 #ifndef BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_SEMAPHORES
Chris@16 128 add_leading_slash(semname, sem_str);
Chris@16 129 #else
Chris@101 130 shared_filepath(semname, sem_str);
Chris@16 131 #endif
Chris@16 132 return 0 == sem_unlink(sem_str.c_str());
Chris@16 133 }
Chris@16 134 catch(...){
Chris@16 135 return false;
Chris@16 136 }
Chris@16 137 }
Chris@16 138
Chris@101 139 #endif //BOOST_INTERPROCESS_POSIX_NAMED_SEMAPHORES
Chris@101 140
Chris@101 141 #ifdef BOOST_INTERPROCESS_POSIX_UNNAMED_SEMAPHORES
Chris@101 142
Chris@16 143 inline void semaphore_init(sem_t *handle, unsigned int initialCount)
Chris@16 144 {
Chris@16 145 int ret = sem_init(handle, 1, initialCount);
Chris@16 146 //According to SUSV3 version 2003 edition, the return value of a successful
Chris@16 147 //sem_init call is not defined, but -1 is returned on failure.
Chris@16 148 //In the future, a successful call might be required to return 0.
Chris@16 149 if(ret == -1){
Chris@101 150 error_info err = system_error_code();
Chris@101 151 throw interprocess_exception(err);
Chris@16 152 }
Chris@16 153 }
Chris@16 154
Chris@16 155 inline void semaphore_destroy(sem_t *handle)
Chris@16 156 {
Chris@16 157 int ret = sem_destroy(handle);
Chris@16 158 if(ret != 0){
Chris@16 159 BOOST_ASSERT(0);
Chris@16 160 }
Chris@16 161 }
Chris@16 162
Chris@101 163 #endif //BOOST_INTERPROCESS_POSIX_UNNAMED_SEMAPHORES
Chris@101 164
Chris@16 165 inline void semaphore_post(sem_t *handle)
Chris@16 166 {
Chris@16 167 int ret = sem_post(handle);
Chris@16 168 if(ret != 0){
Chris@101 169 error_info err = system_error_code();
Chris@101 170 throw interprocess_exception(err);
Chris@16 171 }
Chris@16 172 }
Chris@16 173
Chris@16 174 inline void semaphore_wait(sem_t *handle)
Chris@16 175 {
Chris@16 176 int ret = sem_wait(handle);
Chris@16 177 if(ret != 0){
Chris@101 178 error_info err = system_error_code();
Chris@101 179 throw interprocess_exception(err);
Chris@16 180 }
Chris@16 181 }
Chris@16 182
Chris@16 183 inline bool semaphore_try_wait(sem_t *handle)
Chris@16 184 {
Chris@16 185 int res = sem_trywait(handle);
Chris@16 186 if(res == 0)
Chris@16 187 return true;
Chris@16 188 if(system_error_code() == EAGAIN){
Chris@16 189 return false;
Chris@16 190 }
Chris@101 191 error_info err = system_error_code();
Chris@101 192 throw interprocess_exception(err);
Chris@16 193 }
Chris@16 194
Chris@101 195 #ifndef BOOST_INTERPROCESS_POSIX_TIMEOUTS
Chris@101 196
Chris@101 197 struct semaphore_wrapper_try_wrapper
Chris@101 198 {
Chris@101 199 explicit semaphore_wrapper_try_wrapper(sem_t *handle)
Chris@101 200 : m_handle(handle)
Chris@101 201 {}
Chris@101 202
Chris@101 203 void wait()
Chris@101 204 { semaphore_wait(m_handle); }
Chris@101 205
Chris@101 206 bool try_wait()
Chris@101 207 { return semaphore_try_wait(m_handle); }
Chris@101 208
Chris@101 209 private:
Chris@101 210 sem_t *m_handle;
Chris@101 211 };
Chris@101 212
Chris@101 213 #endif
Chris@101 214
Chris@16 215 inline bool semaphore_timed_wait(sem_t *handle, const boost::posix_time::ptime &abs_time)
Chris@16 216 {
Chris@101 217 #ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
Chris@101 218 //Posix does not support infinity absolute time so handle it here
Chris@16 219 if(abs_time == boost::posix_time::pos_infin){
Chris@16 220 semaphore_wait(handle);
Chris@16 221 return true;
Chris@16 222 }
Chris@101 223
Chris@16 224 timespec tspec = ptime_to_timespec(abs_time);
Chris@16 225 for (;;){
Chris@16 226 int res = sem_timedwait(handle, &tspec);
Chris@16 227 if(res == 0)
Chris@16 228 return true;
Chris@16 229 if (res > 0){
Chris@16 230 //buggy glibc, copy the returned error code to errno
Chris@16 231 errno = res;
Chris@16 232 }
Chris@16 233 if(system_error_code() == ETIMEDOUT){
Chris@16 234 return false;
Chris@16 235 }
Chris@101 236 error_info err = system_error_code();
Chris@101 237 throw interprocess_exception(err);
Chris@16 238 }
Chris@16 239 return false;
Chris@16 240 #else //#ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
Chris@101 241
Chris@101 242 semaphore_wrapper_try_wrapper swtw(handle);
Chris@101 243 ipcdetail::lock_to_wait<semaphore_wrapper_try_wrapper> lw(swtw);
Chris@101 244 return ipcdetail::try_based_timed_lock(lw, abs_time);
Chris@101 245
Chris@16 246 #endif //#ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
Chris@16 247 }
Chris@16 248
Chris@16 249 } //namespace ipcdetail {
Chris@16 250 } //namespace interprocess {
Chris@16 251 } //namespace boost {
Chris@16 252
Chris@16 253 #endif //#ifndef BOOST_INTERPROCESS_POSIX_SEMAPHORE_WRAPPER_HPP