Mercurial > hg > vamp-build-and-test
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 |