diff options
author | Chris Hall <chris.hall@highwayman.com> | 2011-09-02 00:53:59 +0100 |
---|---|---|
committer | Chris Hall <chris.hall@highwayman.com> | 2011-09-02 00:53:59 +0100 |
commit | 3690074a486cfada568975e287d9cbb9e687501f (patch) | |
tree | f6394c1ab1ca8381e9a77acca84f03dc701d10b2 /lib/qtimers.c | |
parent | 3f515315d5b17e432453eef67d7ac9e27bc39461 (diff) | |
download | quagga-3690074a486cfada568975e287d9cbb9e687501f.tar.bz2 quagga-3690074a486cfada568975e287d9cbb9e687501f.tar.xz |
Merging of euro_ix branch into pipework.
Bring in fixes for bgp dumping with pthreaded BGP Engine.
Bring in new "show nexus xxx" command.
Fix removal of '~' prompt.
Diffstat (limited to 'lib/qtimers.c')
-rw-r--r-- | lib/qtimers.c | 94 |
1 files changed, 57 insertions, 37 deletions
diff --git a/lib/qtimers.c b/lib/qtimers.c index ad8da395..9d23eeda 100644 --- a/lib/qtimers.c +++ b/lib/qtimers.c @@ -128,7 +128,7 @@ qtimer_pile_init_new(qtimer_pile qtp) * is returned. */ extern qtime_t -qtimer_pile_top_wait(qtimer_pile qtp, qtime_t max_wait) +qtimer_pile_top_wait(qtimer_pile qtp, qtime_t max_wait, qtime_t now) { qtime_t top_wait ; qtimer qtr = heap_top_item(&qtp->timers) ; @@ -136,7 +136,7 @@ qtimer_pile_top_wait(qtimer_pile qtp, qtime_t max_wait) if (qtr == NULL) return max_wait ; - top_wait = qtr->time - qt_get_monotonic() ; + top_wait = qtr->time - now ; return (top_wait < max_wait) ? top_wait : max_wait ; } ; @@ -158,6 +158,7 @@ extern bool qtimer_pile_dispatch_next(qtimer_pile qtp, qtime_mono_t upto) { qtimer qtr ; + qtr_state_t state ; if (qtimers_debug) qtimer_pile_verify(qtp) ; @@ -167,16 +168,22 @@ qtimer_pile_dispatch_next(qtimer_pile qtp, qtime_mono_t upto) if ((qtr == NULL) || (qtr->time > upto)) return 0 ; - passert((qtp == qtr->pile) && (qtr->active)) ; + passert((qtp == qtr->pile) && (qtr->state == qtrs_active)) ; - qtp->implicit_unset = qtr ; /* Timer must be unset if is still here - when the action function returns */ + qtr->state = qtrs_dispatch | qtrs_unset_pending | qtrs_active ; + /* Timer must be unset if is still here + when the action function returns */ qtr->action(qtr, qtr->timer_info, upto) ; - if (qtp->implicit_unset == qtr) + state = qtr->state ; + qtr->state &= qtrs_active ; /* No longer in dispatch */ + + confirm((qtrs_active != 0) && (qtrs_inactive == 0)) ; + + if ((state & qtrs_free_pending) != 0) + qtimer_free(qtr) ; + else if ((state & qtrs_unset_pending) != 0) qtimer_unset(qtr) ; - else - assert(qtp->implicit_unset == NULL) ; /* check for tidy-ness */ return 1 ; } ; @@ -209,7 +216,7 @@ qtimer_pile_ream(qtimer_pile qtp, free_keep_b free_structure) qtr = heap_ream(&qtp->timers, keep_it) ; /* ream, keeping the heap */ if (qtr != NULL) - qtr->active = false ; /* has been removed from pile */ + qtr->state = qtrs_inactive ; /* has been removed from pile */ else if (free_structure) /* pile is empty, may now free it */ XFREE(MTYPE_QTIMER_PILE, qtp) ; @@ -245,7 +252,7 @@ qtimer_init_new(qtimer qtr, qtimer_pile qtp, * pile -- NULL -- not in any pile (yet) * backlink -- unset * - * active -- false + * state -- qtrs_inactive * * time -- unset * action -- NULL -- no action set (yet) @@ -253,6 +260,7 @@ qtimer_init_new(qtimer qtr, qtimer_pile qtp, * * interval -- unset */ + confirm(qtrs_inactive == 0) ; qtr->pile = qtp ; qtr->action = action ; @@ -264,9 +272,13 @@ qtimer_init_new(qtimer qtr, qtimer_pile qtp, /*------------------------------------------------------------------------------ * Free given timer -- if any. * - * Unsets it first if it is active or pending unset. + * Unsets it first if it is active. * * Returns: NULL + * + * Note: if this is currently a dispatched timer, then does not actually free, + * but leaves that for the dispatch loop to tidy up. The caller is + * expected to assume that the timer has gone, gone. */ extern qtimer qtimer_free(qtimer qtr) @@ -276,10 +288,13 @@ qtimer_free(qtimer qtr) */ if (qtr != NULL) { - if (qtr->active) + if ((qtr->state & qtrs_active) != 0) qtimer_unset(qtr) ; - XFREE(MTYPE_QTIMER, qtr) ; + if ((qtr->state & qtrs_dispatch) == 0) + XFREE(MTYPE_QTIMER, qtr) ; + else + qtr->state = qtrs_dispatch | qtrs_free_pending ; } ; return NULL ; @@ -301,7 +316,7 @@ qtimer_set_pile(qtimer qtr, qtimer_pile qtp) /* Note that if is the current dispatched timer and an unset is still * pending, then it must still be active. */ - if (qtr->active) + if ((qtr->state & qtrs_active) != 0) qtimer_unset(qtr) ; qtr->pile = qtp ; @@ -315,7 +330,9 @@ qtimer_set_pile(qtimer qtr, qtimer_pile qtp) * Sets any given action -- if the action given is NULL, retains previously set * action. * - * If the timer is already active, sets the new time & updates pile. + * If the timer is already active, sets the new time & updates pile. If is the + * dispatched timer, and was pending being unset, then no longer needs to be + * unset. * * Otherwise, sets the time and adds to pile -- making timer active. * @@ -337,22 +354,19 @@ qtimer_set(qtimer qtr, qtime_mono_t when, qtimer_action* action) qtr->time = when ; - if (qtr->active) + if ((qtr->state & qtrs_active) != 0) { /* Is active, so update the timer in the pile. */ heap_update_item(&qtp->timers, qtr) ; - if (qtr == qtp->implicit_unset) - qtp->implicit_unset = NULL ; /* no unset required, now */ + qtr->state &= ~qtrs_unset_pending ; /* no unset required, now */ } else { /* Is not active, so insert the timer into the pile. */ heap_push_item(&qtp->timers, qtr) ; - assert(qtr != qtp->implicit_unset) ; /* because it's not active */ - - qtr->active = true ; + qtr->state |= qtrs_active ; } ; if (action != NULL) @@ -362,12 +376,19 @@ qtimer_set(qtimer qtr, qtime_mono_t when, qtimer_action* action) if (qtimers_debug) qtimer_pile_verify(qtp) ; + + if (qdebug) + assert( (qtr->state == qtrs_active) || + (qtr->state == (qtrs_active | qtrs_dispatch)) ) ; } ; /*------------------------------------------------------------------------------ * Unset given timer * * If the timer is active, removes from pile and sets inactive. + * + * If timer was pending being unset (because is the dispatched timer), then no + * longer needs to be unset. */ extern void qtimer_unset(qtimer qtr) @@ -379,20 +400,19 @@ qtimer_unset(qtimer qtr) if (qtimers_debug) qtimer_pile_verify(qtp) ; - if (qtr->active) + if ((qtr->state & qtrs_active) != 0) { - if (qtr == qtp->implicit_unset) - qtp->implicit_unset = NULL ; /* no unset required, now */ - heap_delete_item(&qtp->timers, qtr) ; + qtr->state &= ~(qtrs_unset_pending | qtrs_active); + /* not active, no unset required, now */ if (qtimers_debug) qtimer_pile_verify(qtp) ; + } ; - qtr->active = false ; - } - else - assert(qtr != qtp->implicit_unset) ; + if (qdebug) + assert( (qtr->state == qtrs_inactive) || + (qtr->state == (qtrs_inactive | qtrs_dispatch)) ) ; } ; /*============================================================================== @@ -406,7 +426,7 @@ qtimer_pile_verify(qtimer_pile qtp) vector_index_t i ; vector_length_t e ; qtimer qtr ; - bool seen = false ; + bool seen_dispatch ; assert(qtp != NULL) ; @@ -421,23 +441,23 @@ qtimer_pile_verify(qtimer_pile qtp) v = th->v ; e = vector_end(v) ; + seen_dispatch = false ; for (i = 0 ; i < e ; ++i) { qtr = vector_get_item(v, i) ; assert(qtr != NULL) ; - if (qtr == qtp->implicit_unset) + if (qtr->state != qtrs_active) { - assert(!seen) ; - seen = true ; + assert((qtr->state & qtrs_dispatch) != 0) ; + assert((qtr->state & qtrs_free_pending) == 0) ; + assert((qtr->state & qtrs_active) != 0) ; + assert(!seen_dispatch) ; + seen_dispatch = true ; } ; - assert(qtr->active) ; - assert(qtr->pile == qtp) ; assert(qtr->backlink == i) ; assert(qtr->action != NULL) ; } ; - - assert(seen || (qtp->implicit_unset == NULL)) ; } ; |