diff options
author | Chris Hall (GMCH) <chris.hall@highwayman.com> | 2009-12-09 17:59:03 +0000 |
---|---|---|
committer | Chris Hall (GMCH) <chris.hall@highwayman.com> | 2009-12-09 17:59:03 +0000 |
commit | b3edb8b2b5d1e9c7b23bad9de6802e89c3a8fd0b (patch) | |
tree | 8f71c2d4efb98e8644c881c3d055ebf29b6ddb4c /lib/qpthreads.c | |
parent | 482674bb1e9401fa4f954fb03cdc84ad9908845f (diff) | |
download | quagga-b3edb8b2b5d1e9c7b23bad9de6802e89c3a8fd0b.tar.bz2 quagga-b3edb8b2b5d1e9c7b23bad9de6802e89c3a8fd0b.tar.xz |
Ensure all timeouts are timeout times in qtime_mono_t.
Introduced separate types for qtime_mono_t and qtime_real_t, to
distinguish the time base of a given value.
Revised all users of timeouts so that they are all expressed as
qtime_mono_t values, so are all Quagga monotonic time based.
Revised qpt_cond_timedwait() so that all condition variables use the
same timebase (CLOCK_MONOTONIC if available, by default). Now all
timeout times are qtime_mono_t, and are converted to whatever the
condition variable is set to, if necessary.
Added explicit timeout to mqueue.
Fixed qps_pselect() to zeroise result vectors if no fds are
reported pending -- seems the O/S does not do this.
Diffstat (limited to 'lib/qpthreads.c')
-rw-r--r-- | lib/qpthreads.c | 40 |
1 files changed, 31 insertions, 9 deletions
diff --git a/lib/qpthreads.c b/lib/qpthreads.c index 94ec37c0..5dd0cfc4 100644 --- a/lib/qpthreads.c +++ b/lib/qpthreads.c @@ -445,7 +445,6 @@ qpt_cond_t* qpt_cond_init(qpt_cond_t* cv, enum qpt_cond_options opts) { pthread_condattr_t cond_attr ; - int clock ; int err ; if (cv == NULL) @@ -459,19 +458,12 @@ qpt_cond_init(qpt_cond_t* cv, enum qpt_cond_options opts) switch(opts) { case qpt_cond_quagga: - clock = QPT_COND_CLOCK_ID ; - break ; - case qpt_cond_realtime: - clock = CLOCK_REALTIME ; - break ; - case qpt_cond_monotonic: - clock = CLOCK_MONOTONIC ; break ; default: zabort("Invalid qpt_cond option") ; } ; - err = pthread_condattr_setclock(&cond_attr, clock); + err = pthread_condattr_setclock(&cond_attr, QPT_COND_CLOCK_ID); if (err != 0) zabort_err("pthread_condattr_setclock failed", err) ; @@ -508,6 +500,36 @@ qpt_cond_destroy(qpt_cond_t* cv, int free_cond) return NULL ; } ; +/* Wait for given condition variable or time-out. + * + * Returns: wait succeeded (1 => success, 0 => timed-out). + * + * NB: timeout time is a qtime_mono_t (monotonic time). + * + * Has to check the return value, so zabort_errno if not EBUSY. + */ + +int +qpt_cond_timedwait(qpt_cond_t* cv, qpt_mutex_t* mx, qtime_mono_t timeout_time) +{ + struct timespec ts ; + + if (QPT_COND_CLOCK_ID != CLOCK_MONOTONIC) + { + timeout_time = qt_clock_gettime(QPT_COND_CLOCK_ID) + + (timeout_time - qt_get_monotonic()) ; + } ; + + int err = pthread_cond_timedwait(cv, mx, qtime2timespec(&ts, timeout_time)) ; + if (err == 0) + return 1 ; /* got condition */ + if (err == ETIMEDOUT) + return 0 ; /* got time-out */ + + zabort_err("pthread_cond_timedwait failed", err) ; + /* crunch */ +} ; + /*============================================================================== * Signal Handling. */ |