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