From: Mark Andrews Date: Wed, 24 Oct 2007 01:05:29 +0000 (+0000) Subject: 2254. [bug] timer.c:dispatch() failed to lock timer->lock X-Git-Tag: v9.4.2rc2~18 X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=8283c44c5c8f71d4bc2d147ac2168765f586019f;p=thirdparty%2Fbind9.git 2254. [bug] timer.c:dispatch() failed to lock timer->lock when reading timer->idle allowing it to see intermediate values as timer->idle was reset by isc_timer_touch(). [RT #17243] --- diff --git a/CHANGES b/CHANGES index 77c9e8ccbf3..b7ca153ce78 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,9 @@ +2254. [bug] timer.c:dispatch() failed to lock timer->lock + when reading timer->idle allowing it to see + intermediate values as timer->idle was reset by + isc_timer_touch(). [RT #17243] + --- 9.4.2rc1 released --- 2251. [doc] Update memstatistics-file documentation to reflect diff --git a/lib/isc/timer.c b/lib/isc/timer.c index 4b96fa5e4ef..a50a880e418 100644 --- a/lib/isc/timer.c +++ b/lib/isc/timer.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: timer.c,v 1.73.18.5 2005/11/30 03:44:39 marka Exp $ */ +/* $Id: timer.c,v 1.73.18.6 2007/10/24 01:05:29 marka Exp $ */ /*! \file */ @@ -581,6 +581,7 @@ dispatch(isc_timermgr_t *manager, isc_time_t *now) { isc_eventtype_t type = 0; isc_timer_t *timer; isc_result_t result; + isc_boolean_t idle; /*! * The caller must be holding the manager lock. @@ -612,23 +613,33 @@ dispatch(isc_timermgr_t *manager, isc_time_t *now) { type = ISC_TIMEREVENT_LIFE; post_event = ISC_TRUE; need_schedule = ISC_FALSE; - } else if (!isc_time_isepoch(&timer->idle) && - isc_time_compare(now, - &timer->idle) >= 0) { - type = ISC_TIMEREVENT_IDLE; - post_event = ISC_TRUE; - need_schedule = ISC_FALSE; } else { - /* - * Idle timer has been touched; reschedule. - */ - XTRACEID(isc_msgcat_get(isc_msgcat, - ISC_MSGSET_TIMER, - ISC_MSG_IDLERESCHED, - "idle reschedule"), - timer); - post_event = ISC_FALSE; - need_schedule = ISC_TRUE; + idle = ISC_FALSE; + + LOCK(&timer->lock); + if (!isc_time_isepoch(&timer->idle) && + isc_time_compare(now, + &timer->idle) >= 0) { + idle = ISC_TRUE; + } + UNLOCK(&timer->lock); + if (idle) { + type = ISC_TIMEREVENT_IDLE; + post_event = ISC_TRUE; + need_schedule = ISC_FALSE; + } else { + /* + * Idle timer has been touched; + * reschedule. + */ + XTRACEID(isc_msgcat_get(isc_msgcat, + ISC_MSGSET_TIMER, + ISC_MSG_IDLERESCHED, + "idle reschedule"), + timer); + post_event = ISC_FALSE; + need_schedule = ISC_TRUE; + } } if (post_event) {