Commit abb46dc5 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

Fix handling of EINTR in sleeping functions.

This will not change your life.
parent 898c9279
...@@ -128,6 +128,9 @@ static inline unsigned mprec( void ) ...@@ -128,6 +128,9 @@ static inline unsigned mprec( void )
static unsigned prec = 0; static unsigned prec = 0;
static volatile mtime_t cached_time = 0; static volatile mtime_t cached_time = 0;
#if (_POSIX_MONOTONIC_CLOCK - 0 < 0)
# define CLOCK_MONOTONIC CLOCK_REALTIME
#endif
/** /**
* Return high precision date * Return high precision date
...@@ -142,10 +145,8 @@ mtime_t mdate( void ) ...@@ -142,10 +145,8 @@ mtime_t mdate( void )
#if defined (HAVE_CLOCK_NANOSLEEP) #if defined (HAVE_CLOCK_NANOSLEEP)
struct timespec ts; struct timespec ts;
# if (_POSIX_MONOTONIC_CLOCK - 0 >= 0)
/* Try to use POSIX monotonic clock if available */ /* Try to use POSIX monotonic clock if available */
if( clock_gettime( CLOCK_MONOTONIC, &ts ) ) if( clock_gettime( CLOCK_MONOTONIC, &ts ) == EINVAL )
# endif
/* Run-time fallback to real-time clock (always available) */ /* Run-time fallback to real-time clock (always available) */
(void)clock_gettime( CLOCK_REALTIME, &ts ); (void)clock_gettime( CLOCK_REALTIME, &ts );
...@@ -262,10 +263,14 @@ void mwait( mtime_t date ) ...@@ -262,10 +263,14 @@ void mwait( mtime_t date )
lldiv_t d = lldiv( date, 1000000 ); lldiv_t d = lldiv( date, 1000000 );
struct timespec ts = { d.quot, d.rem * 1000 }; struct timespec ts = { d.quot, d.rem * 1000 };
# if (_POSIX_MONOTONIC_CLOCK - 0 >= 0) int val;
if( clock_nanosleep( CLOCK_MONOTONIC, TIMER_ABSTIME, &ts, NULL ) ) while( ( val = clock_nanosleep( CLOCK_MONOTONIC, TIMER_ABSTIME, &ts,
# endif NULL ) ) == EINTR );
clock_nanosleep( CLOCK_REALTIME, TIMER_ABSTIME, &ts, NULL ); if( val == EINVAL )
{
ts.tv_sec = d.quot; ts.tv_nsec = d.rem * 1000;
while( clock_nanosleep( CLOCK_REALTIME, 0, &ts, NULL ) == EINTR );
}
#else #else
mtime_t delay = date - mdate(); mtime_t delay = date - mdate();
...@@ -289,10 +294,13 @@ void msleep( mtime_t delay ) ...@@ -289,10 +294,13 @@ void msleep( mtime_t delay )
lldiv_t d = lldiv( delay, 1000000 ); lldiv_t d = lldiv( delay, 1000000 );
struct timespec ts = { d.quot, d.rem * 1000 }; struct timespec ts = { d.quot, d.rem * 1000 };
# if (_POSIX_MONOTONIC_CLOCK - 0 >= 0) int val;
if( clock_nanosleep( CLOCK_MONOTONIC, 0, &ts, NULL ) ) while( ( val = clock_nanosleep( CLOCK_MONOTONIC, 0, &ts, &ts ) ) == EINTR );
# endif if( val == EINVAL )
clock_nanosleep( CLOCK_REALTIME, 0, &ts, NULL ); {
ts.tv_sec = d.quot; ts.tv_nsec = d.rem * 1000;
while( clock_nanosleep( CLOCK_REALTIME, 0, &ts, &ts ) == EINTR );
}
#elif defined( HAVE_KERNEL_OS_H ) #elif defined( HAVE_KERNEL_OS_H )
snooze( delay ); snooze( delay );
...@@ -312,7 +320,7 @@ void msleep( mtime_t delay ) ...@@ -312,7 +320,7 @@ void msleep( mtime_t delay )
ts_delay.tv_sec = delay / 1000000; ts_delay.tv_sec = delay / 1000000;
ts_delay.tv_nsec = (delay % 1000000) * 1000; ts_delay.tv_nsec = (delay % 1000000) * 1000;
nanosleep( &ts_delay, NULL ); while( nanosleep( &ts_delay, &ts_delay ) && ( errno == EINTR ) );
#else #else
struct timeval tv_delay; struct timeval tv_delay;
...@@ -320,10 +328,8 @@ void msleep( mtime_t delay ) ...@@ -320,10 +328,8 @@ void msleep( mtime_t delay )
tv_delay.tv_sec = delay / 1000000; tv_delay.tv_sec = delay / 1000000;
tv_delay.tv_usec = delay % 1000000; tv_delay.tv_usec = delay % 1000000;
/* select() return value should be tested, since several possible errors /* If a signal is caught, you are screwed. Update your OS to nanosleep()
* can occur. However, they should only happen in very particular occasions * or clock_nanosleep() if this is an issue. */
* (i.e. when a signal is sent to the thread, or when memory is full), and
* can be ignored. */
select( 0, NULL, NULL, NULL, &tv_delay ); select( 0, NULL, NULL, NULL, &tv_delay );
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment