mirror of
https://github.com/boostorg/interprocess.git
synced 2026-01-19 04:12:13 +00:00
Define and use DISABLE_BOOST_INTERPROCESS_EINTR_RETRY macro to handle EINTR in GCC compatible compilers.
This commit is contained in:
@@ -509,24 +509,27 @@ inline file_handle_t file_handle_from_mapping_handle(mapping_handle_t hnd)
|
||||
inline bool create_directory(const char *path)
|
||||
{
|
||||
::mode_t m = ::mode_t(0777);
|
||||
return ::mkdir(path, m) == 0;
|
||||
int r = BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::mkdir(path, m));
|
||||
return r == 0;
|
||||
}
|
||||
|
||||
inline bool open_or_create_directory(const char *path)
|
||||
{
|
||||
::mode_t m = ::mode_t(0777);
|
||||
return ::mkdir(path, m) == 0 || (errno == EEXIST);
|
||||
int r = BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::mkdir(path, m));
|
||||
return r == 0 || (errno == EEXIST);
|
||||
}
|
||||
|
||||
inline bool open_or_create_shared_directory(const char *path)
|
||||
{
|
||||
const ::mode_t m = ::mode_t(01777);
|
||||
const bool created = ::mkdir(path, m) == 0;
|
||||
int rc = BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::mkdir(path, m));
|
||||
const bool created = rc == 0;
|
||||
const bool created_or_exists = created || (errno == EEXIST);
|
||||
//Try to maximize the chance that the sticky bit is set in shared dirs
|
||||
//created with old versions that did not set it (for security reasons)
|
||||
const bool chmoded = ::chmod(path, m) == 0;
|
||||
return created ? chmoded : created_or_exists;
|
||||
rc = BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::chmod(path, m));
|
||||
return created ? (rc == 0) : created_or_exists;
|
||||
}
|
||||
|
||||
inline bool remove_directory(const char *path)
|
||||
@@ -547,9 +550,10 @@ inline file_handle_t create_new_file
|
||||
(const char *name, mode_t mode, const permissions & perm = permissions(), bool temporary = false)
|
||||
{
|
||||
(void)temporary;
|
||||
int ret = ::open(name, ((int)mode) | O_EXCL | O_CREAT, perm.get_permissions());
|
||||
int ret = BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::open(name, ((int)mode) | O_EXCL | O_CREAT, perm.get_permissions()));
|
||||
if(ret >= 0){
|
||||
::fchmod(ret, perm.get_permissions());
|
||||
int rc = BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::fchmod(ret, perm.get_permissions()));
|
||||
(void)rc;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -562,13 +566,14 @@ inline file_handle_t create_or_open_file
|
||||
//We need a loop to change permissions correctly using fchmod, since
|
||||
//with "O_CREAT only" ::open we don't know if we've created or opened the file.
|
||||
while(true){
|
||||
ret = ::open(name, ((int)mode) | O_EXCL | O_CREAT, perm.get_permissions());
|
||||
ret = BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::open(name, ((int)mode) | O_EXCL | O_CREAT, perm.get_permissions()));
|
||||
if(ret >= 0){
|
||||
::fchmod(ret, perm.get_permissions());
|
||||
int rc = BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::fchmod(ret, perm.get_permissions()));
|
||||
(void)rc;
|
||||
break;
|
||||
}
|
||||
else if(errno == EEXIST){
|
||||
if((ret = ::open(name, (int)mode)) >= 0 || errno != ENOENT){
|
||||
if((ret = BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::open(name, (int)mode))) >= 0 || errno != ENOENT){
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -583,11 +588,11 @@ inline file_handle_t open_existing_file
|
||||
(const char *name, mode_t mode, bool temporary = false)
|
||||
{
|
||||
(void)temporary;
|
||||
return ::open(name, (int)mode);
|
||||
return BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::open(name, (int)mode));
|
||||
}
|
||||
|
||||
inline bool delete_file(const char *name)
|
||||
{ return ::unlink(name) == 0; }
|
||||
{ return BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::unlink(name)) == 0; }
|
||||
|
||||
inline bool truncate_file (file_handle_t hnd, std::size_t size)
|
||||
{
|
||||
@@ -597,13 +602,13 @@ inline bool truncate_file (file_handle_t hnd, std::size_t size)
|
||||
errno = EINVAL;
|
||||
return false;
|
||||
}
|
||||
return 0 == ::ftruncate(hnd, off_t(size));
|
||||
return 0 == BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::ftruncate(hnd, off_t(size)));
|
||||
}
|
||||
|
||||
inline bool get_file_size(file_handle_t hnd, offset_t &size)
|
||||
{
|
||||
struct stat data;
|
||||
bool ret = 0 == ::fstat(hnd, &data);
|
||||
bool ret = 0 == BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::fstat(hnd, &data));
|
||||
if(ret){
|
||||
size = data.st_size;
|
||||
}
|
||||
@@ -611,16 +616,16 @@ inline bool get_file_size(file_handle_t hnd, offset_t &size)
|
||||
}
|
||||
|
||||
inline bool set_file_pointer(file_handle_t hnd, offset_t off, file_pos_t pos)
|
||||
{ return ((off_t)(-1)) != ::lseek(hnd, off, (int)pos); }
|
||||
{ return ((off_t)(-1)) != BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::lseek(hnd, off, (int)pos)); }
|
||||
|
||||
inline bool get_file_pointer(file_handle_t hnd, offset_t &off)
|
||||
{
|
||||
off = ::lseek(hnd, 0, SEEK_CUR);
|
||||
off = BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::lseek(hnd, 0, SEEK_CUR));
|
||||
return off != ((off_t)-1);
|
||||
}
|
||||
|
||||
inline bool write_file(file_handle_t hnd, const void *data, std::size_t numdata)
|
||||
{ return (ssize_t(numdata)) == ::write(hnd, data, numdata); }
|
||||
{ return (ssize_t(numdata)) == BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::write(hnd, data, numdata)); }
|
||||
|
||||
inline file_handle_t invalid_file()
|
||||
{ return -1; }
|
||||
@@ -635,7 +640,7 @@ inline bool acquire_file_lock(file_handle_t hnd)
|
||||
lock.l_whence = SEEK_SET;
|
||||
lock.l_start = 0;
|
||||
lock.l_len = 0;
|
||||
return -1 != ::fcntl(hnd, F_SETLKW, &lock);
|
||||
return -1 != BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::fcntl(hnd, F_SETLKW, &lock));
|
||||
}
|
||||
|
||||
inline bool try_acquire_file_lock(file_handle_t hnd, bool &acquired)
|
||||
@@ -645,7 +650,7 @@ inline bool try_acquire_file_lock(file_handle_t hnd, bool &acquired)
|
||||
lock.l_whence = SEEK_SET;
|
||||
lock.l_start = 0;
|
||||
lock.l_len = 0;
|
||||
int ret = ::fcntl(hnd, F_SETLK, &lock);
|
||||
int ret = BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::fcntl(hnd, F_SETLK, &lock));
|
||||
if(ret == -1){
|
||||
return (errno == EAGAIN || errno == EACCES) ?
|
||||
(acquired = false, true) : false;
|
||||
@@ -660,7 +665,7 @@ inline bool release_file_lock(file_handle_t hnd)
|
||||
lock.l_whence = SEEK_SET;
|
||||
lock.l_start = 0;
|
||||
lock.l_len = 0;
|
||||
return -1 != ::fcntl(hnd, F_SETLK, &lock);
|
||||
return -1 != BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::fcntl(hnd, F_SETLK, &lock));
|
||||
}
|
||||
|
||||
inline bool acquire_file_lock_sharable(file_handle_t hnd)
|
||||
@@ -670,7 +675,7 @@ inline bool acquire_file_lock_sharable(file_handle_t hnd)
|
||||
lock.l_whence = SEEK_SET;
|
||||
lock.l_start = 0;
|
||||
lock.l_len = 0;
|
||||
return -1 != ::fcntl(hnd, F_SETLKW, &lock);
|
||||
return -1 != BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::fcntl(hnd, F_SETLKW, &lock));
|
||||
}
|
||||
|
||||
inline bool try_acquire_file_lock_sharable(file_handle_t hnd, bool &acquired)
|
||||
@@ -680,7 +685,7 @@ inline bool try_acquire_file_lock_sharable(file_handle_t hnd, bool &acquired)
|
||||
lock.l_whence = SEEK_SET;
|
||||
lock.l_start = 0;
|
||||
lock.l_len = 0;
|
||||
int ret = ::fcntl(hnd, F_SETLK, &lock);
|
||||
int ret = BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::fcntl(hnd, F_SETLK, &lock));
|
||||
if(ret == -1){
|
||||
return (errno == EAGAIN || errno == EACCES) ?
|
||||
(acquired = false, true) : false;
|
||||
@@ -693,30 +698,30 @@ inline bool release_file_lock_sharable(file_handle_t hnd)
|
||||
|
||||
#if 0
|
||||
inline bool acquire_file_lock(file_handle_t hnd)
|
||||
{ return 0 == ::flock(hnd, LOCK_EX); }
|
||||
{ return 0 == BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::flock(hnd, LOCK_EX)); }
|
||||
|
||||
inline bool try_acquire_file_lock(file_handle_t hnd, bool &acquired)
|
||||
{
|
||||
int ret = ::flock(hnd, LOCK_EX | LOCK_NB);
|
||||
int ret = BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::flock(hnd, LOCK_EX | LOCK_NB));
|
||||
acquired = ret == 0;
|
||||
return (acquired || errno == EWOULDBLOCK);
|
||||
}
|
||||
|
||||
inline bool release_file_lock(file_handle_t hnd)
|
||||
{ return 0 == ::flock(hnd, LOCK_UN); }
|
||||
{ return 0 == BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::flock(hnd, LOCK_UN)); }
|
||||
|
||||
inline bool acquire_file_lock_sharable(file_handle_t hnd)
|
||||
{ return 0 == ::flock(hnd, LOCK_SH); }
|
||||
{ return 0 == BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::flock(hnd, LOCK_SH)); }
|
||||
|
||||
inline bool try_acquire_file_lock_sharable(file_handle_t hnd, bool &acquired)
|
||||
{
|
||||
int ret = ::flock(hnd, LOCK_SH | LOCK_NB);
|
||||
int ret = BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::flock(hnd, LOCK_SH | LOCK_NB));
|
||||
acquired = ret == 0;
|
||||
return (acquired || errno == EWOULDBLOCK);
|
||||
}
|
||||
|
||||
inline bool release_file_lock_sharable(file_handle_t hnd)
|
||||
{ return 0 == ::flock(hnd, LOCK_UN); }
|
||||
{ return 0 == BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::flock(hnd, LOCK_UN)); }
|
||||
#endif
|
||||
|
||||
inline bool delete_subdirectories_recursive
|
||||
|
||||
@@ -441,7 +441,7 @@ inline void thread_sleep_tick()
|
||||
rqt.tv_nsec = (long)get_system_tick_ns()/2;
|
||||
|
||||
struct timespec rmn;
|
||||
while (0 != ::nanosleep(&rqt, &rmn) && errno == EINTR) {
|
||||
while (0 != BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::nanosleep(&rqt, &rmn)) && errno == EINTR) {
|
||||
rqt.tv_sec = rmn.tv_sec;
|
||||
rqt.tv_nsec = rmn.tv_nsec;
|
||||
}
|
||||
@@ -454,7 +454,7 @@ inline void thread_sleep_ms(unsigned int ms)
|
||||
rqt.tv_nsec = static_cast<long int>((ms%1000u)*1000000u);
|
||||
|
||||
struct timespec rmn;
|
||||
while (0 != ::nanosleep(&rqt, &rmn) && errno == EINTR) {
|
||||
while (0 != BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::nanosleep(&rqt, &rmn)) && errno == EINTR) {
|
||||
rqt.tv_sec = rmn.tv_sec;
|
||||
rqt.tv_nsec = rmn.tv_nsec;
|
||||
}
|
||||
|
||||
@@ -351,4 +351,28 @@ namespace boost {
|
||||
#define BOOST_INTERPROCESS_GCC_COMPATIBLE_HAS_DIAGNOSTIC_IGNORED
|
||||
#endif
|
||||
|
||||
|
||||
////////////////////////////////////////////
|
||||
//
|
||||
// BOOST_INTERPROCESS_EINTR_RETRY
|
||||
//
|
||||
////////////////////////////////////////////
|
||||
|
||||
//#define DISABLE_BOOST_INTERPROCESS_EINTR_RETRY
|
||||
#if !defined(DISABLE_BOOST_INTERPROCESS_EINTR_RETRY) && defined(__GNUC__)
|
||||
|
||||
/* taken from glibc unistd.h and fixes musl */
|
||||
#define BOOST_INTERPROCESS_EINTR_RETRY(RESULTTYPE, FAILUREVALUE, EXPRESSION) \
|
||||
(__extension__ \
|
||||
({ RESULTTYPE __result; \
|
||||
do __result = (RESULTTYPE) (EXPRESSION); \
|
||||
while (__result == FAILUREVALUE && errno == EINTR); \
|
||||
__result; }))
|
||||
|
||||
#else //!defined(DISABLE_BOOST_INTERPROCESS_EINTR_RETRY) && defined(__GNUC__)
|
||||
|
||||
#define BOOST_INTERPROCESS_EINTR_RETRY(RESULTTYPE, FAILUREVALUE, EXPRESSION) ((RESULTTYPE)(EXPRESSION))
|
||||
|
||||
#endif //!defined(DISABLE_BOOST_INTERPROCESS_EINTR_RETRY) && defined(__GNUC__)
|
||||
|
||||
#endif //#ifndef BOOST_INTERPROCESS_DETAIL_WORKAROUND_HPP
|
||||
|
||||
@@ -70,7 +70,7 @@ inline bool semaphore_open
|
||||
case DoOpen:
|
||||
{
|
||||
//No addition
|
||||
handle = ::sem_open(name.c_str(), oflag);
|
||||
handle = BOOST_INTERPROCESS_EINTR_RETRY(sem_t*, BOOST_INTERPROCESS_POSIX_SEM_FAILED, ::sem_open(name.c_str(), oflag));
|
||||
}
|
||||
break;
|
||||
case DoOpenOrCreate:
|
||||
@@ -78,7 +78,9 @@ inline bool semaphore_open
|
||||
{
|
||||
while(1){
|
||||
oflag = (O_CREAT | O_EXCL);
|
||||
handle = ::sem_open(name.c_str(), oflag, perm.get_permissions(), count);
|
||||
handle = BOOST_INTERPROCESS_EINTR_RETRY
|
||||
( sem_t*, BOOST_INTERPROCESS_POSIX_SEM_FAILED
|
||||
, ::sem_open(name.c_str(), oflag, perm.get_permissions(), count));
|
||||
if(handle != BOOST_INTERPROCESS_POSIX_SEM_FAILED){
|
||||
//We can't change semaphore permissions!
|
||||
//::fchmod(handle, perm.get_permissions());
|
||||
@@ -86,7 +88,9 @@ inline bool semaphore_open
|
||||
}
|
||||
else if(errno == EEXIST && type == DoOpenOrCreate){
|
||||
oflag = 0;
|
||||
if( (handle = ::sem_open(name.c_str(), oflag)) != BOOST_INTERPROCESS_POSIX_SEM_FAILED
|
||||
if( (handle = BOOST_INTERPROCESS_EINTR_RETRY
|
||||
(sem_t*, BOOST_INTERPROCESS_POSIX_SEM_FAILED, ::sem_open(name.c_str(), oflag)))
|
||||
!= BOOST_INTERPROCESS_POSIX_SEM_FAILED
|
||||
|| (errno != ENOENT) ){
|
||||
break;
|
||||
}
|
||||
@@ -177,7 +181,7 @@ inline void semaphore_post(sem_t *handle)
|
||||
|
||||
inline void semaphore_wait(sem_t *handle)
|
||||
{
|
||||
int ret = sem_wait(handle);
|
||||
int ret = BOOST_INTERPROCESS_EINTR_RETRY(int, -1, sem_wait(handle));
|
||||
if(ret != 0){
|
||||
error_info err = system_error_code();
|
||||
throw interprocess_exception(err);
|
||||
@@ -186,7 +190,7 @@ inline void semaphore_wait(sem_t *handle)
|
||||
|
||||
inline bool semaphore_try_wait(sem_t *handle)
|
||||
{
|
||||
int res = sem_trywait(handle);
|
||||
int res = BOOST_INTERPROCESS_EINTR_RETRY(int, -1, sem_trywait(handle));
|
||||
if(res == 0)
|
||||
return true;
|
||||
if(system_error_code() == EAGAIN){
|
||||
@@ -228,7 +232,7 @@ inline bool semaphore_timed_wait(sem_t *handle, const TimePoint &abs_time)
|
||||
|
||||
timespec tspec = timepoint_to_timespec(abs_time);
|
||||
for (;;){
|
||||
int res = sem_timedwait(handle, &tspec);
|
||||
int res = BOOST_INTERPROCESS_EINTR_RETRY(int, -1, sem_timedwait(handle, &tspec));
|
||||
if(res == 0)
|
||||
return true;
|
||||
if (res > 0){
|
||||
|
||||
Reference in New Issue
Block a user