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