Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:38:25

0001 //////////////////////////////////////////////////////////////////////////////
0002 //
0003 // (C) Copyright Ion Gaztanaga 2009-2012. Distributed under the Boost
0004 // Software License, Version 1.0. (See accompanying file
0005 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 // See http://www.boost.org/libs/interprocess for documentation.
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 //defined(BOOST_INTERPROCESS_WINDOWS)
0042 
0043 #include <fcntl.h>
0044 #include <sys/stat.h>
0045 #include <unistd.h>
0046 
0047 #endif   //defined(BOOST_INTERPROCESS_WINDOWS)
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    //This reference count counts the number of modules attached
0062    //to the shared memory and lock file. This serves to unlink
0063    //the locking file and shared memory when all modules are
0064    //done with the global memory (shared memory)
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/*lock_file_contents_length()*/);
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; //Initialize attached count
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 //UNIX
0174 
0175 struct locking_file_serial_id
0176 {
0177    int fd;
0178    dev_t st_dev;
0179    ino_t st_ino;
0180    //This reference count counts the number of modules attached
0181    //to the shared memory and lock file. This serves to unlink
0182    //the locking file and shared memory when all modules are
0183    //done with the global memory (shared memory)
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; //Initialize attached count
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 }  //namespace ipcdetail{
0297 }  //namespace interprocess{
0298 }  //namespace boost{
0299 
0300 #include <boost/interprocess/detail/config_end.hpp>
0301 
0302 #endif   //BOOST_INTERPROCESS_FILE_LOCKING_HELPERS_HPP