File indexing completed on 2025-01-18 09:38:25
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_INTERPROCESS_FILE_LOCKING_HELPERS_HPP
0012 #define BOOST_INTERPROCESS_FILE_LOCKING_HELPERS_HPP
0013
0014 #ifndef BOOST_CONFIG_HPP
0015 # include <boost/config.hpp>
0016 #endif
0017 #
0018 #if defined(BOOST_HAS_PRAGMA_ONCE)
0019 #pragma once
0020 #endif
0021
0022 #include <boost/interprocess/detail/config_begin.hpp>
0023 #include <boost/interprocess/detail/workaround.hpp>
0024
0025 #include <sstream>
0026 #include <string>
0027 #include <sys/types.h>
0028 #include <sys/stat.h>
0029 #include <errno.h>
0030 #include <cstddef>
0031 #include <boost/interprocess/detail/os_file_functions.hpp>
0032
0033 #include <boost/interprocess/detail/shared_dir_helpers.hpp>
0034
0035 #if defined(BOOST_INTERPROCESS_WINDOWS)
0036
0037 #include <fcntl.h>
0038 #include <io.h>
0039 #include <sys/locking.h>
0040
0041 #else
0042
0043 #include <fcntl.h>
0044 #include <sys/stat.h>
0045 #include <unistd.h>
0046
0047 #endif
0048
0049 namespace boost{
0050 namespace interprocess{
0051 namespace ipcdetail{
0052
0053 #if defined(BOOST_INTERPROCESS_WINDOWS)
0054
0055 struct locking_file_serial_id
0056 {
0057 int fd;
0058 unsigned long dwVolumeSerialNumber;
0059 unsigned long nFileIndexHigh;
0060 unsigned long nFileIndexLow;
0061
0062
0063
0064
0065 volatile boost::uint32_t modules_attached_to_gmem_count;
0066 };
0067
0068 inline bool lock_locking_file(int fd)
0069 {
0070 int ret = 0;
0071 while(ret != 0 && errno == EDEADLK){
0072 ret = _locking(fd, _LK_LOCK, 1);
0073 }
0074 return 0 == ret;
0075 }
0076
0077 inline bool try_lock_locking_file(int fd)
0078 {
0079 return 0 == _locking(fd, _LK_NBLCK , 1);
0080 }
0081
0082 inline int open_or_create_and_lock_file(const char *name)
0083 {
0084 permissions p;
0085 p.set_unrestricted();
0086 while(1){
0087 file_handle_t handle = create_or_open_file(name, read_write, p);
0088 int fd = _open_osfhandle((intptr_t)handle, _O_TEXT);
0089 if(fd < 0){
0090 close_file(handle);
0091 return fd;
0092 }
0093 if(!try_lock_locking_file(fd)){
0094 _close(fd);
0095 return -1;
0096 }
0097 struct _stat s;
0098 if(0 == _stat(name, &s)){
0099 return fd;
0100 }
0101 else{
0102 _close(fd);
0103 }
0104 }
0105 }
0106
0107 inline int try_open_and_lock_file(const char *name)
0108 {
0109 file_handle_t handle = open_existing_file(name, read_write);
0110 int fd = _open_osfhandle((intptr_t)handle, _O_TEXT);
0111 if(fd < 0){
0112 close_file(handle);
0113 return fd;
0114 }
0115 if(!try_lock_locking_file(fd)){
0116 _close(fd);
0117 return -1;
0118 }
0119 return fd;
0120 }
0121
0122 inline void close_lock_file(int fd)
0123 { _close(fd); }
0124
0125 inline bool is_valid_fd(int fd)
0126 {
0127 struct _stat s;
0128 return EBADF != _fstat(fd, &s);
0129 }
0130
0131 inline bool is_normal_file(int fd)
0132 {
0133 if(_isatty(fd))
0134 return false;
0135 struct _stat s;
0136 if(0 != _fstat(fd, &s))
0137 return false;
0138 return 0 != (s.st_mode & _S_IFREG);
0139 }
0140
0141 inline std::size_t get_size(int fd)
0142 {
0143 struct _stat s;
0144 if(0 != _fstat(fd, &s))
0145 return 0u;
0146 return (std::size_t)s.st_size;
0147 }
0148
0149 inline bool fill_file_serial_id(int fd, locking_file_serial_id &id)
0150 {
0151 winapi::interprocess_by_handle_file_information info;
0152 if(!winapi::get_file_information_by_handle((void*)_get_osfhandle(fd), &info))
0153 return false;
0154 id.fd = fd;
0155 id.dwVolumeSerialNumber = info.dwVolumeSerialNumber;
0156 id.nFileIndexHigh = info.nFileIndexHigh;
0157 id.nFileIndexLow = info.nFileIndexLow;
0158 id.modules_attached_to_gmem_count = 1;
0159 return true;
0160 }
0161
0162 inline bool compare_file_serial(int fd, const locking_file_serial_id &id)
0163 {
0164 winapi::interprocess_by_handle_file_information info;
0165 if(!winapi::get_file_information_by_handle((void*)_get_osfhandle(fd), &info))
0166 return false;
0167
0168 return id.dwVolumeSerialNumber == info.dwVolumeSerialNumber &&
0169 id.nFileIndexHigh == info.nFileIndexHigh &&
0170 id.nFileIndexLow == info.nFileIndexLow;
0171 }
0172
0173 #else
0174
0175 struct locking_file_serial_id
0176 {
0177 int fd;
0178 dev_t st_dev;
0179 ino_t st_ino;
0180
0181
0182
0183
0184 volatile boost::uint32_t modules_attached_to_gmem_count;
0185 };
0186
0187 inline bool lock_locking_file(int fd)
0188 {
0189 int ret = 0;
0190 while(ret != 0 && errno != EINTR){
0191 struct flock lock;
0192 lock.l_type = F_WRLCK;
0193 lock.l_whence = SEEK_SET;
0194 lock.l_start = 0;
0195 lock.l_len = 1;
0196 ret = fcntl (fd, F_SETLKW, &lock);
0197 }
0198 return 0 == ret;
0199 }
0200
0201 inline bool try_lock_locking_file(int fd)
0202 {
0203 struct flock lock;
0204 lock.l_type = F_WRLCK;
0205 lock.l_whence = SEEK_SET;
0206 lock.l_start = 0;
0207 lock.l_len = 1;
0208 return 0 == fcntl (fd, F_SETLK, &lock);
0209 }
0210
0211 inline int open_or_create_and_lock_file(const char *name)
0212 {
0213 permissions p;
0214 p.set_unrestricted();
0215 while(1){
0216 int fd = create_or_open_file(name, read_write, p);
0217 if(fd < 0){
0218 return fd;
0219 }
0220 if(!try_lock_locking_file(fd)){
0221 close(fd);
0222 return -1;
0223 }
0224 struct stat s;
0225 if(0 == stat(name, &s)){
0226 return fd;
0227 }
0228 else{
0229 close(fd);
0230 }
0231 }
0232 }
0233
0234 inline int try_open_and_lock_file(const char *name)
0235 {
0236 int fd = open_existing_file(name, read_write);
0237 if(fd < 0){
0238 return fd;
0239 }
0240 if(!try_lock_locking_file(fd)){
0241 close(fd);
0242 return -1;
0243 }
0244 return fd;
0245 }
0246
0247 inline void close_lock_file(int fd)
0248 { close(fd); }
0249
0250 inline bool is_valid_fd(int fd)
0251 {
0252 struct stat s;
0253 return EBADF != fstat(fd, &s);
0254 }
0255
0256 inline bool is_normal_file(int fd)
0257 {
0258 struct stat s;
0259 if(0 != fstat(fd, &s))
0260 return false;
0261 return 0 != (s.st_mode & S_IFREG);
0262 }
0263
0264 inline std::size_t get_size(int fd)
0265 {
0266 struct stat s;
0267 if(0 != fstat(fd, &s))
0268 return 0u;
0269 return (std::size_t)s.st_size;
0270 }
0271
0272 inline bool fill_file_serial_id(int fd, locking_file_serial_id &id)
0273 {
0274 struct stat s;
0275 if(0 != fstat(fd, &s))
0276 return false;
0277 id.fd = fd;
0278 id.st_dev = s.st_dev;
0279 id.st_ino = s.st_ino;
0280 id.modules_attached_to_gmem_count = 1;
0281 return true;
0282 }
0283
0284 inline bool compare_file_serial(int fd, const locking_file_serial_id &id)
0285 {
0286 struct stat info;
0287 if(0 != fstat(fd, &info))
0288 return false;
0289
0290 return id.st_dev == info.st_dev &&
0291 id.st_ino == info.st_ino;
0292 }
0293
0294 #endif
0295
0296 }
0297 }
0298 }
0299
0300 #include <boost/interprocess/detail/config_end.hpp>
0301
0302 #endif