- struct timespec nowtime;
- int rc;
-
- assert (p_timed_thread != NULL);
-
- /* adjust wait time to now if absolute_time drifted behind */
- now (&nowtime);
- if ( ((nowtime.tv_sec * 1000000000) + nowtime.tv_nsec) >
- ((p_timed_thread->absolute_time.tv_sec * 1000000000) + p_timed_thread->absolute_time.tv_nsec) )
- {
- p_timed_thread->absolute_time.tv_sec = nowtime.tv_sec;
- p_timed_thread->absolute_time.tv_nsec = nowtime.tv_nsec;
- }
-
- /* acquire runnable_cond mutex */
- if (pthread_mutex_lock (&p_timed_thread->runnable_mutex))
- return (-1); /* could not acquire runnable_cond mutex, so tell caller to exit thread */
-
- /* release mutex and wait until future time for runnable_cond to signal */
- rc = pthread_cond_timedwait (&p_timed_thread->runnable_cond,
- &p_timed_thread->runnable_mutex,
- &p_timed_thread->absolute_time);
- /* mutex re-acquired, so release it */
- pthread_mutex_unlock (&p_timed_thread->runnable_mutex);
-
- /* absolute future time for next pass */
- p_timed_thread->absolute_time.tv_sec += p_timed_thread->interval_time.tv_sec;
- p_timed_thread->absolute_time.tv_nsec += p_timed_thread->interval_time.tv_nsec;
-
- if (rc==0)
- return 1; /* runnable_cond was signaled, so tell caller to exit thread */
-
- /* tell caller not to exit yet */
- return 0;
+ struct timespec now_time;
+ int rc;
+
+ assert(p_timed_thread != NULL);
+
+ /* acquire runnable_cond mutex */
+ if (pthread_mutex_lock(&p_timed_thread->runnable_mutex)) {
+ /* could not acquire runnable_cond mutex,
+ * so tell caller to exit thread */
+ return -1;
+ }
+
+ if (p_timed_thread->die) {
+ /* if we were kindly asked to die, then die */
+ return 1;
+ }
+
+ if (override_wait_time && now(&p_timed_thread->wait_time)) {
+ return -1;
+ }
+
+ /* release mutex and wait until future time for runnable_cond to signal */
+ rc = pthread_cond_timedwait(&p_timed_thread->runnable_cond,
+ &p_timed_thread->runnable_mutex, &p_timed_thread->wait_time);
+ /* mutex re-acquired, so release it */
+ pthread_mutex_unlock(&p_timed_thread->runnable_mutex);
+
+ if (now(&now_time)) {
+ return -1;
+ }
+
+ if (rc == 0) {
+ /* runnable_cond was signaled, so tell caller to exit thread */
+ return 1;
+ }
+
+ /* absolute future time for next pass */
+ p_timed_thread->wait_time.tv_sec += p_timed_thread->interval_time.tv_sec;
+ p_timed_thread->wait_time.tv_nsec += p_timed_thread->interval_time.tv_nsec;
+ p_timed_thread->wait_time.tv_sec += p_timed_thread->wait_time.tv_nsec / 1000000000;
+ p_timed_thread->wait_time.tv_nsec = p_timed_thread->wait_time.tv_nsec % 1000000000;
+
+ /* ensure our future wait time is sane */
+ if (p_timed_thread->wait_time.tv_sec > (now_time.tv_sec + p_timed_thread->interval_time.tv_sec) || p_timed_thread->wait_time.tv_sec < now_time.tv_sec) {
+ p_timed_thread->wait_time.tv_sec = now_time.tv_sec + p_timed_thread->interval_time.tv_sec;
+ p_timed_thread->wait_time.tv_nsec = now_time.tv_nsec + p_timed_thread->interval_time.tv_nsec;
+ p_timed_thread->wait_time.tv_sec += p_timed_thread->wait_time.tv_nsec / 1000000000;
+ p_timed_thread->wait_time.tv_nsec = p_timed_thread->wait_time.tv_nsec % 1000000000;
+ }
+
+ /* tell caller not to exit yet */
+ return 0;