]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
2254. [bug] timer.c:dispatch() failed to lock timer->lock
authorMark Andrews <marka@isc.org>
Wed, 24 Oct 2007 00:57:23 +0000 (00:57 +0000)
committerMark Andrews <marka@isc.org>
Wed, 24 Oct 2007 00:57:23 +0000 (00:57 +0000)
                        when reading timer->idle allowing it to see
                        intermediate values as timer->idle was reset by
                        isc_timer_touch(). [RT #17243]

CHANGES
lib/isc/timer.c

diff --git a/CHANGES b/CHANGES
index 4835cde532b02964862ea6148f3b638fb95726fa..4bab20c1d89651a0f2336cc35e9cd0d137ae4f4b 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,8 @@
+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.5.0a7 released ---
 
 2253.  [func]          "max-cache-size" defaults to 32M.
index ccad8f6692f9530fce7d4dcf601c617f773fb08c..fb599796d81ab8ecbcb7ffe55beac81df33d3fe2 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: timer.c,v 1.80 2007/06/19 23:47:17 tbox Exp $ */
+/* $Id: timer.c,v 1.81 2007/10/24 00:57:23 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) {