Skip to content
Permalink
Browse files
Fix race condition for celixThreadCondition_timedwaitRelative.
Adjusting system clock between clock_gettime(CLOCK_REALTIME) and
pthread_cond_timedwait may lead to unexpected long blocking. To fix it,
we use CLOCK_MONOTONIC on platforms that support it, while on Mac OS
which does not support CLOCK_MONOTONIC we have
pthread_cond_timedwait_relative_np.
  • Loading branch information
PengZheng committed Nov 15, 2021
1 parent bb9179a commit efa578e029cc342b118c68f71ce1a33d7947e8d9
Showing 1 changed file with 20 additions and 7 deletions.
@@ -145,7 +145,23 @@ celix_status_t celixThreadMutexAttr_settype(celix_thread_mutexattr_t *attr, int
}

celix_status_t celixThreadCondition_init(celix_thread_cond_t *condition, celix_thread_condattr_t *attr) {
#ifdef __APPLE__
return pthread_cond_init(condition, attr);
#else
celix_status_t status = CELIX_SUCCESS;
if(attr) {
status = pthread_condattr_setclock(attr, CLOCK_MONOTONIC);
CELIX_DO_IF(status, pthread_cond_init(condition, attr));
}
else {
celix_thread_condattr_t condattr;
(void)pthread_condattr_init(&condattr); // always return 0
status = pthread_condattr_setclock(&condattr, CLOCK_MONOTONIC);
CELIX_DO_IF(status, pthread_cond_init(condition, &condattr));
(void)pthread_condattr_destroy(&condattr); // always return 0
}
return status;
#endif
}

celix_status_t celixThreadCondition_destroy(celix_thread_cond_t *condition) {
@@ -158,18 +174,15 @@ celix_status_t celixThreadCondition_wait(celix_thread_cond_t *cond, celix_thread

#ifdef __APPLE__
celix_status_t celixThreadCondition_timedwaitRelative(celix_thread_cond_t *cond, celix_thread_mutex_t *mutex, long seconds, long nanoseconds) {
struct timeval tv;
struct timespec time;
gettimeofday(&tv, NULL);
TIMEVAL_TO_TIMESPEC(&tv, &time)
time.tv_sec += seconds;
time.tv_nsec += nanoseconds;
return pthread_cond_timedwait(cond, mutex, &time);
time.tv_sec = seconds;
time.tv_nsec = nanoseconds;
return pthread_cond_timedwait_relative_np(cond, mutex, &time);
}
#else
celix_status_t celixThreadCondition_timedwaitRelative(celix_thread_cond_t *cond, celix_thread_mutex_t *mutex, long seconds, long nanoseconds) {
struct timespec time;
clock_gettime(CLOCK_REALTIME, &time);
clock_gettime(CLOCK_MONOTONIC, &time);
time.tv_sec += seconds;
time.tv_nsec += nanoseconds;
return pthread_cond_timedwait(cond, mutex, &time);

0 comments on commit efa578e

Please sign in to comment.