Skip to content

Commit 75c3c9e

Browse files
committed
Define and use DISABLE_BOOST_INTERPROCESS_EINTR_RETRY macro to handle EINTR in GCC compatible compilers.
1 parent 3761f39 commit 75c3c9e

File tree

4 files changed

+69
-36
lines changed

4 files changed

+69
-36
lines changed

include/boost/interprocess/detail/os_file_functions.hpp

Lines changed: 33 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -509,24 +509,27 @@ inline file_handle_t file_handle_from_mapping_handle(mapping_handle_t hnd)
509509
inline bool create_directory(const char *path)
510510
{
511511
::mode_t m = ::mode_t(0777);
512-
return ::mkdir(path, m) == 0;
512+
int r = BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::mkdir(path, m));
513+
return r == 0;
513514
}
514515

515516
inline bool open_or_create_directory(const char *path)
516517
{
517518
::mode_t m = ::mode_t(0777);
518-
return ::mkdir(path, m) == 0 || (errno == EEXIST);
519+
int r = BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::mkdir(path, m));
520+
return r == 0 || (errno == EEXIST);
519521
}
520522

521523
inline bool open_or_create_shared_directory(const char *path)
522524
{
523525
const ::mode_t m = ::mode_t(01777);
524-
const bool created = ::mkdir(path, m) == 0;
526+
int rc = BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::mkdir(path, m));
527+
const bool created = rc == 0;
525528
const bool created_or_exists = created || (errno == EEXIST);
526529
//Try to maximize the chance that the sticky bit is set in shared dirs
527530
//created with old versions that did not set it (for security reasons)
528-
const bool chmoded = ::chmod(path, m) == 0;
529-
return created ? chmoded : created_or_exists;
531+
rc = BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::chmod(path, m));
532+
return created ? (rc == 0) : created_or_exists;
530533
}
531534

532535
inline bool remove_directory(const char *path)
@@ -547,9 +550,10 @@ inline file_handle_t create_new_file
547550
(const char *name, mode_t mode, const permissions & perm = permissions(), bool temporary = false)
548551
{
549552
(void)temporary;
550-
int ret = ::open(name, ((int)mode) | O_EXCL | O_CREAT, perm.get_permissions());
553+
int ret = BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::open(name, ((int)mode) | O_EXCL | O_CREAT, perm.get_permissions()));
551554
if(ret >= 0){
552-
::fchmod(ret, perm.get_permissions());
555+
int rc = BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::fchmod(ret, perm.get_permissions()));
556+
(void)rc;
553557
}
554558
return ret;
555559
}
@@ -562,13 +566,14 @@ inline file_handle_t create_or_open_file
562566
//We need a loop to change permissions correctly using fchmod, since
563567
//with "O_CREAT only" ::open we don't know if we've created or opened the file.
564568
while(true){
565-
ret = ::open(name, ((int)mode) | O_EXCL | O_CREAT, perm.get_permissions());
569+
ret = BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::open(name, ((int)mode) | O_EXCL | O_CREAT, perm.get_permissions()));
566570
if(ret >= 0){
567-
::fchmod(ret, perm.get_permissions());
571+
int rc = BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::fchmod(ret, perm.get_permissions()));
572+
(void)rc;
568573
break;
569574
}
570575
else if(errno == EEXIST){
571-
if((ret = ::open(name, (int)mode)) >= 0 || errno != ENOENT){
576+
if((ret = BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::open(name, (int)mode))) >= 0 || errno != ENOENT){
572577
break;
573578
}
574579
}
@@ -583,11 +588,11 @@ inline file_handle_t open_existing_file
583588
(const char *name, mode_t mode, bool temporary = false)
584589
{
585590
(void)temporary;
586-
return ::open(name, (int)mode);
591+
return BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::open(name, (int)mode));
587592
}
588593

589594
inline bool delete_file(const char *name)
590-
{ return ::unlink(name) == 0; }
595+
{ return BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::unlink(name)) == 0; }
591596

592597
inline bool truncate_file (file_handle_t hnd, std::size_t size)
593598
{
@@ -597,30 +602,30 @@ inline bool truncate_file (file_handle_t hnd, std::size_t size)
597602
errno = EINVAL;
598603
return false;
599604
}
600-
return 0 == ::ftruncate(hnd, off_t(size));
605+
return 0 == BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::ftruncate(hnd, off_t(size)));
601606
}
602607

603608
inline bool get_file_size(file_handle_t hnd, offset_t &size)
604609
{
605610
struct stat data;
606-
bool ret = 0 == ::fstat(hnd, &data);
611+
bool ret = 0 == BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::fstat(hnd, &data));
607612
if(ret){
608613
size = data.st_size;
609614
}
610615
return ret;
611616
}
612617

613618
inline bool set_file_pointer(file_handle_t hnd, offset_t off, file_pos_t pos)
614-
{ return ((off_t)(-1)) != ::lseek(hnd, off, (int)pos); }
619+
{ return ((off_t)(-1)) != BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::lseek(hnd, off, (int)pos)); }
615620

616621
inline bool get_file_pointer(file_handle_t hnd, offset_t &off)
617622
{
618-
off = ::lseek(hnd, 0, SEEK_CUR);
623+
off = BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::lseek(hnd, 0, SEEK_CUR));
619624
return off != ((off_t)-1);
620625
}
621626

622627
inline bool write_file(file_handle_t hnd, const void *data, std::size_t numdata)
623-
{ return (ssize_t(numdata)) == ::write(hnd, data, numdata); }
628+
{ return (ssize_t(numdata)) == BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::write(hnd, data, numdata)); }
624629

625630
inline file_handle_t invalid_file()
626631
{ return -1; }
@@ -635,7 +640,7 @@ inline bool acquire_file_lock(file_handle_t hnd)
635640
lock.l_whence = SEEK_SET;
636641
lock.l_start = 0;
637642
lock.l_len = 0;
638-
return -1 != ::fcntl(hnd, F_SETLKW, &lock);
643+
return -1 != BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::fcntl(hnd, F_SETLKW, &lock));
639644
}
640645

641646
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)
645650
lock.l_whence = SEEK_SET;
646651
lock.l_start = 0;
647652
lock.l_len = 0;
648-
int ret = ::fcntl(hnd, F_SETLK, &lock);
653+
int ret = BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::fcntl(hnd, F_SETLK, &lock));
649654
if(ret == -1){
650655
return (errno == EAGAIN || errno == EACCES) ?
651656
(acquired = false, true) : false;
@@ -660,7 +665,7 @@ inline bool release_file_lock(file_handle_t hnd)
660665
lock.l_whence = SEEK_SET;
661666
lock.l_start = 0;
662667
lock.l_len = 0;
663-
return -1 != ::fcntl(hnd, F_SETLK, &lock);
668+
return -1 != BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::fcntl(hnd, F_SETLK, &lock));
664669
}
665670

666671
inline bool acquire_file_lock_sharable(file_handle_t hnd)
@@ -670,7 +675,7 @@ inline bool acquire_file_lock_sharable(file_handle_t hnd)
670675
lock.l_whence = SEEK_SET;
671676
lock.l_start = 0;
672677
lock.l_len = 0;
673-
return -1 != ::fcntl(hnd, F_SETLKW, &lock);
678+
return -1 != BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::fcntl(hnd, F_SETLKW, &lock));
674679
}
675680

676681
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)
680685
lock.l_whence = SEEK_SET;
681686
lock.l_start = 0;
682687
lock.l_len = 0;
683-
int ret = ::fcntl(hnd, F_SETLK, &lock);
688+
int ret = BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::fcntl(hnd, F_SETLK, &lock));
684689
if(ret == -1){
685690
return (errno == EAGAIN || errno == EACCES) ?
686691
(acquired = false, true) : false;
@@ -693,30 +698,30 @@ inline bool release_file_lock_sharable(file_handle_t hnd)
693698

694699
#if 0
695700
inline bool acquire_file_lock(file_handle_t hnd)
696-
{ return 0 == ::flock(hnd, LOCK_EX); }
701+
{ return 0 == BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::flock(hnd, LOCK_EX)); }
697702

698703
inline bool try_acquire_file_lock(file_handle_t hnd, bool &acquired)
699704
{
700-
int ret = ::flock(hnd, LOCK_EX | LOCK_NB);
705+
int ret = BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::flock(hnd, LOCK_EX | LOCK_NB));
701706
acquired = ret == 0;
702707
return (acquired || errno == EWOULDBLOCK);
703708
}
704709

705710
inline bool release_file_lock(file_handle_t hnd)
706-
{ return 0 == ::flock(hnd, LOCK_UN); }
711+
{ return 0 == BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::flock(hnd, LOCK_UN)); }
707712

708713
inline bool acquire_file_lock_sharable(file_handle_t hnd)
709-
{ return 0 == ::flock(hnd, LOCK_SH); }
714+
{ return 0 == BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::flock(hnd, LOCK_SH)); }
710715

711716
inline bool try_acquire_file_lock_sharable(file_handle_t hnd, bool &acquired)
712717
{
713-
int ret = ::flock(hnd, LOCK_SH | LOCK_NB);
718+
int ret = BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::flock(hnd, LOCK_SH | LOCK_NB));
714719
acquired = ret == 0;
715720
return (acquired || errno == EWOULDBLOCK);
716721
}
717722

718723
inline bool release_file_lock_sharable(file_handle_t hnd)
719-
{ return 0 == ::flock(hnd, LOCK_UN); }
724+
{ return 0 == BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::flock(hnd, LOCK_UN)); }
720725
#endif
721726

722727
inline bool delete_subdirectories_recursive

include/boost/interprocess/detail/os_thread_functions.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,7 @@ inline void thread_sleep_tick()
441441
rqt.tv_nsec = (long)get_system_tick_ns()/2;
442442

443443
struct timespec rmn;
444-
while (0 != ::nanosleep(&rqt, &rmn) && errno == EINTR) {
444+
while (0 != BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::nanosleep(&rqt, &rmn)) && errno == EINTR) {
445445
rqt.tv_sec = rmn.tv_sec;
446446
rqt.tv_nsec = rmn.tv_nsec;
447447
}
@@ -454,7 +454,7 @@ inline void thread_sleep_ms(unsigned int ms)
454454
rqt.tv_nsec = static_cast<long int>((ms%1000u)*1000000u);
455455

456456
struct timespec rmn;
457-
while (0 != ::nanosleep(&rqt, &rmn) && errno == EINTR) {
457+
while (0 != BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::nanosleep(&rqt, &rmn)) && errno == EINTR) {
458458
rqt.tv_sec = rmn.tv_sec;
459459
rqt.tv_nsec = rmn.tv_nsec;
460460
}

include/boost/interprocess/detail/workaround.hpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,4 +351,28 @@ namespace boost {
351351
#define BOOST_INTERPROCESS_GCC_COMPATIBLE_HAS_DIAGNOSTIC_IGNORED
352352
#endif
353353

354+
355+
////////////////////////////////////////////
356+
//
357+
// BOOST_INTERPROCESS_EINTR_RETRY
358+
//
359+
////////////////////////////////////////////
360+
361+
//#define DISABLE_BOOST_INTERPROCESS_EINTR_RETRY
362+
#if !defined(DISABLE_BOOST_INTERPROCESS_EINTR_RETRY) && defined(__GNUC__)
363+
364+
/* taken from glibc unistd.h and fixes musl */
365+
#define BOOST_INTERPROCESS_EINTR_RETRY(RESULTTYPE, FAILUREVALUE, EXPRESSION) \
366+
(__extension__ \
367+
({ RESULTTYPE __result; \
368+
do __result = (RESULTTYPE) (EXPRESSION); \
369+
while (__result == FAILUREVALUE && errno == EINTR); \
370+
__result; }))
371+
372+
#else //!defined(DISABLE_BOOST_INTERPROCESS_EINTR_RETRY) && defined(__GNUC__)
373+
374+
#define BOOST_INTERPROCESS_EINTR_RETRY(RESULTTYPE, FAILUREVALUE, EXPRESSION) ((RESULTTYPE)(EXPRESSION))
375+
376+
#endif //!defined(DISABLE_BOOST_INTERPROCESS_EINTR_RETRY) && defined(__GNUC__)
377+
354378
#endif //#ifndef BOOST_INTERPROCESS_DETAIL_WORKAROUND_HPP

include/boost/interprocess/sync/posix/semaphore_wrapper.hpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,23 +70,27 @@ inline bool semaphore_open
7070
case DoOpen:
7171
{
7272
//No addition
73-
handle = ::sem_open(name.c_str(), oflag);
73+
handle = BOOST_INTERPROCESS_EINTR_RETRY(sem_t*, BOOST_INTERPROCESS_POSIX_SEM_FAILED, ::sem_open(name.c_str(), oflag));
7474
}
7575
break;
7676
case DoOpenOrCreate:
7777
case DoCreate:
7878
{
7979
while(1){
8080
oflag = (O_CREAT | O_EXCL);
81-
handle = ::sem_open(name.c_str(), oflag, perm.get_permissions(), count);
81+
handle = BOOST_INTERPROCESS_EINTR_RETRY
82+
( sem_t*, BOOST_INTERPROCESS_POSIX_SEM_FAILED
83+
, ::sem_open(name.c_str(), oflag, perm.get_permissions(), count));
8284
if(handle != BOOST_INTERPROCESS_POSIX_SEM_FAILED){
8385
//We can't change semaphore permissions!
8486
//::fchmod(handle, perm.get_permissions());
8587
break;
8688
}
8789
else if(errno == EEXIST && type == DoOpenOrCreate){
8890
oflag = 0;
89-
if( (handle = ::sem_open(name.c_str(), oflag)) != BOOST_INTERPROCESS_POSIX_SEM_FAILED
91+
if( (handle = BOOST_INTERPROCESS_EINTR_RETRY
92+
(sem_t*, BOOST_INTERPROCESS_POSIX_SEM_FAILED, ::sem_open(name.c_str(), oflag)))
93+
!= BOOST_INTERPROCESS_POSIX_SEM_FAILED
9094
|| (errno != ENOENT) ){
9195
break;
9296
}
@@ -177,7 +181,7 @@ inline void semaphore_post(sem_t *handle)
177181

178182
inline void semaphore_wait(sem_t *handle)
179183
{
180-
int ret = sem_wait(handle);
184+
int ret = BOOST_INTERPROCESS_EINTR_RETRY(int, -1, sem_wait(handle));
181185
if(ret != 0){
182186
error_info err = system_error_code();
183187
throw interprocess_exception(err);
@@ -186,7 +190,7 @@ inline void semaphore_wait(sem_t *handle)
186190

187191
inline bool semaphore_try_wait(sem_t *handle)
188192
{
189-
int res = sem_trywait(handle);
193+
int res = BOOST_INTERPROCESS_EINTR_RETRY(int, -1, sem_trywait(handle));
190194
if(res == 0)
191195
return true;
192196
if(system_error_code() == EAGAIN){
@@ -228,7 +232,7 @@ inline bool semaphore_timed_wait(sem_t *handle, const TimePoint &abs_time)
228232

229233
timespec tspec = timepoint_to_timespec(abs_time);
230234
for (;;){
231-
int res = sem_timedwait(handle, &tspec);
235+
int res = BOOST_INTERPROCESS_EINTR_RETRY(int, -1, sem_timedwait(handle, &tspec));
232236
if(res == 0)
233237
return true;
234238
if (res > 0){

0 commit comments

Comments
 (0)