]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/interprocess/include/boost/interprocess/detail/file_locking_helpers.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / interprocess / include / boost / interprocess / detail / file_locking_helpers.hpp
CommitLineData
7c673cae
FG
1//////////////////////////////////////////////////////////////////////////////
2//
3// (C) Copyright Ion Gaztanaga 2009-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_FILE_LOCKING_HELPERS_HPP
12#define BOOST_INTERPROCESS_FILE_LOCKING_HELPERS_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/config_begin.hpp>
23#include <boost/interprocess/detail/workaround.hpp>
24
25#include <sstream>
26#include <string>
27#include <sys/types.h>
28#include <sys/stat.h>
29#include <errno.h>
30#include <cstddef>
31#include <boost/interprocess/detail/os_file_functions.hpp>
32
33#include <boost/interprocess/detail/shared_dir_helpers.hpp>
34
35#if defined(BOOST_INTERPROCESS_WINDOWS)
36
37#include <fcntl.h>
38#include <io.h>
39#include <sys/locking.h>
40
41#else //defined(BOOST_INTERPROCESS_WINDOWS)
42
43#include <fcntl.h>
44#include <sys/stat.h>
45#include <unistd.h>
46
47#endif //defined(BOOST_INTERPROCESS_WINDOWS)
48
49namespace boost{
50namespace interprocess{
51namespace ipcdetail{
52
53#if defined(BOOST_INTERPROCESS_WINDOWS)
54
55struct locking_file_serial_id
56{
57 int fd;
58 unsigned long dwVolumeSerialNumber;
59 unsigned long nFileIndexHigh;
60 unsigned long nFileIndexLow;
61 //This reference count counts the number of modules attached
62 //to the shared memory and lock file. This serves to unlink
63 //the locking file and shared memory when all modules are
64 //done with the global memory (shared memory)
65 volatile boost::uint32_t modules_attached_to_gmem_count;
66};
67
68inline bool lock_locking_file(int fd)
69{
70 int ret = 0;
71 while(ret != 0 && errno == EDEADLK){
72 ret = _locking(fd, _LK_LOCK, 1/*lock_file_contents_length()*/);
73 }
74 return 0 == ret;
75}
76
77inline bool try_lock_locking_file(int fd)
78{
79 return 0 == _locking(fd, _LK_NBLCK , 1);
80}
81
82inline int open_or_create_and_lock_file(const char *name)
83{
84 permissions p;
85 p.set_unrestricted();
86 while(1){
87 file_handle_t handle = create_or_open_file(name, read_write, p);
88 int fd = _open_osfhandle((intptr_t)handle, _O_TEXT);
89 if(fd < 0){
90 close_file(handle);
91 return fd;
92 }
93 if(!try_lock_locking_file(fd)){
94 _close(fd);
95 return -1;
96 }
97 struct _stat s;
98 if(0 == _stat(name, &s)){
99 return fd;
100 }
101 else{
102 _close(fd);
103 }
104 }
105}
106
107inline int try_open_and_lock_file(const char *name)
108{
109 file_handle_t handle = open_existing_file(name, read_write);
110 int fd = _open_osfhandle((intptr_t)handle, _O_TEXT);
111 if(fd < 0){
112 close_file(handle);
113 return fd;
114 }
115 if(!try_lock_locking_file(fd)){
116 _close(fd);
117 return -1;
118 }
119 return fd;
120}
121
122inline void close_lock_file(int fd)
123{ _close(fd); }
124
125inline bool is_valid_fd(int fd)
126{
127 struct _stat s;
128 return EBADF != _fstat(fd, &s);
129}
130
131inline bool is_normal_file(int fd)
132{
133 if(_isatty(fd))
134 return false;
135 struct _stat s;
136 if(0 != _fstat(fd, &s))
137 return false;
138 return 0 != (s.st_mode & _S_IFREG);
139}
140
141inline std::size_t get_size(int fd)
142{
143 struct _stat s;
144 if(0 != _fstat(fd, &s))
145 return 0u;
146 return (std::size_t)s.st_size;
147}
148
149inline bool fill_file_serial_id(int fd, locking_file_serial_id &id)
150{
151 winapi::interprocess_by_handle_file_information info;
152 if(!winapi::get_file_information_by_handle((void*)_get_osfhandle(fd), &info))
153 return false;
154 id.fd = fd;
155 id.dwVolumeSerialNumber = info.dwVolumeSerialNumber;
156 id.nFileIndexHigh = info.nFileIndexHigh;
157 id.nFileIndexLow = info.nFileIndexLow;
158 id.modules_attached_to_gmem_count = 1; //Initialize attached count
159 return true;
160}
161
162inline bool compare_file_serial(int fd, const locking_file_serial_id &id)
163{
164 winapi::interprocess_by_handle_file_information info;
165 if(!winapi::get_file_information_by_handle((void*)_get_osfhandle(fd), &info))
166 return false;
167
168 return id.dwVolumeSerialNumber == info.dwVolumeSerialNumber &&
169 id.nFileIndexHigh == info.nFileIndexHigh &&
170 id.nFileIndexLow == info.nFileIndexLow;
171}
172
173#else //UNIX
174
175struct locking_file_serial_id
176{
177 int fd;
178 dev_t st_dev;
179 ino_t st_ino;
180 //This reference count counts the number of modules attached
181 //to the shared memory and lock file. This serves to unlink
182 //the locking file and shared memory when all modules are
183 //done with the global memory (shared memory)
184 volatile boost::uint32_t modules_attached_to_gmem_count;
185};
186
187inline bool lock_locking_file(int fd)
188{
189 int ret = 0;
190 while(ret != 0 && errno != EINTR){
191 struct flock lock;
192 lock.l_type = F_WRLCK;
193 lock.l_whence = SEEK_SET;
194 lock.l_start = 0;
195 lock.l_len = 1;
196 ret = fcntl (fd, F_SETLKW, &lock);
197 }
198 return 0 == ret;
199}
200
201inline bool try_lock_locking_file(int fd)
202{
203 struct flock lock;
204 lock.l_type = F_WRLCK;
205 lock.l_whence = SEEK_SET;
206 lock.l_start = 0;
207 lock.l_len = 1;
208 return 0 == fcntl (fd, F_SETLK, &lock);
209}
210
211inline int open_or_create_and_lock_file(const char *name)
212{
213 permissions p;
214 p.set_unrestricted();
215 while(1){
216 int fd = create_or_open_file(name, read_write, p);
217 if(fd < 0){
218 return fd;
219 }
220 if(!try_lock_locking_file(fd)){
221 close(fd);
222 return -1;
223 }
224 struct stat s;
225 if(0 == stat(name, &s)){
226 return fd;
227 }
228 else{
229 close(fd);
230 }
231 }
232}
233
234inline int try_open_and_lock_file(const char *name)
235{
236 int fd = open_existing_file(name, read_write);
237 if(fd < 0){
238 return fd;
239 }
240 if(!try_lock_locking_file(fd)){
241 close(fd);
242 return -1;
243 }
244 return fd;
245}
246
247inline void close_lock_file(int fd)
248{ close(fd); }
249
250inline bool is_valid_fd(int fd)
251{
252 struct stat s;
253 return EBADF != fstat(fd, &s);
254}
255
256inline bool is_normal_file(int fd)
257{
258 struct stat s;
259 if(0 != fstat(fd, &s))
260 return false;
261 return 0 != (s.st_mode & S_IFREG);
262}
263
264inline std::size_t get_size(int fd)
265{
266 struct stat s;
267 if(0 != fstat(fd, &s))
268 return 0u;
269 return (std::size_t)s.st_size;
270}
271
272inline bool fill_file_serial_id(int fd, locking_file_serial_id &id)
273{
274 struct stat s;
275 if(0 != fstat(fd, &s))
276 return false;
277 id.fd = fd;
278 id.st_dev = s.st_dev;
279 id.st_ino = s.st_ino;
280 id.modules_attached_to_gmem_count = 1; //Initialize attached count
281 return true;
282}
283
284inline bool compare_file_serial(int fd, const locking_file_serial_id &id)
285{
286 struct stat info;
287 if(0 != fstat(fd, &info))
288 return false;
289
290 return id.st_dev == info.st_dev &&
291 id.st_ino == info.st_ino;
292}
293
294#endif
295
296} //namespace ipcdetail{
297} //namespace interprocess{
298} //namespace boost{
299
300#include <boost/interprocess/detail/config_end.hpp>
301
302#endif //BOOST_INTERPROCESS_FILE_LOCKING_HELPERS_HPP