summaryrefslogtreecommitdiffstats
path: root/lib/qpthreads.c
diff options
context:
space:
mode:
authorChris Hall (GMCH) <chris.hall@highwayman.com>2009-12-09 17:59:03 +0000
committerChris Hall (GMCH) <chris.hall@highwayman.com>2009-12-09 17:59:03 +0000
commitb3edb8b2b5d1e9c7b23bad9de6802e89c3a8fd0b (patch)
tree8f71c2d4efb98e8644c881c3d055ebf29b6ddb4c /lib/qpthreads.c
parent482674bb1e9401fa4f954fb03cdc84ad9908845f (diff)
downloadquagga-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.c40
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.
*/