2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-29 21:47:59 +00:00

allow timer to be inactive; use isc_task_purgerange

This commit is contained in:
Bob Halley 1999-05-10 22:50:31 +00:00
parent d6b0e99380
commit d13284da19
2 changed files with 51 additions and 16 deletions

View File

@ -74,6 +74,7 @@
#include <isc/time.h> #include <isc/time.h>
#include <isc/task.h> #include <isc/task.h>
#include <isc/event.h> #include <isc/event.h>
#include <isc/eventclass.h>
#include <isc/lang.h> #include <isc/lang.h>
ISC_LANG_BEGINDECLS ISC_LANG_BEGINDECLS
@ -86,18 +87,20 @@ typedef struct isc_timer isc_timer_t;
typedef struct isc_timermgr isc_timermgr_t; typedef struct isc_timermgr isc_timermgr_t;
typedef enum { typedef enum {
isc_timertype_ticker = 0, isc_timertype_once isc_timertype_ticker = 0,
isc_timertype_once = 1,
isc_timertype_inactive = 2
} isc_timertype_t; } isc_timertype_t;
typedef struct isc_timerevent { typedef struct isc_timerevent {
struct isc_event common; struct isc_event common;
/* XXX Anything else? XXX */
} isc_timerevent_t; } isc_timerevent_t;
#define ISC_TIMEREVENT_FIRSTEVENT (ISC_EVENTCLASS_TIMER + 0)
#define ISC_TIMEREVENT_TICK (ISC_EVENTCLASS_TIMER + 1) #define ISC_TIMEREVENT_TICK (ISC_EVENTCLASS_TIMER + 1)
#define ISC_TIMEREVENT_IDLE (ISC_EVENTCLASS_TIMER + 2) #define ISC_TIMEREVENT_IDLE (ISC_EVENTCLASS_TIMER + 2)
#define ISC_TIMEREVENT_LIFE (ISC_EVENTCLASS_TIMER + 3) #define ISC_TIMEREVENT_LIFE (ISC_EVENTCLASS_TIMER + 3)
#define ISC_TIMEREVENT_LASTEVENT (ISC_EVENTCLASS_TIMER + 65535)
/*** /***
*** Timer and Timer Manager Functions *** Timer and Timer Manager Functions
@ -140,7 +143,8 @@ isc_timer_create(isc_timermgr_t *manager,
* *
* 'action' is a valid action * 'action' is a valid action
* *
* 'expires' and 'interval' may not both be 0 * (type == isc_timertype_inactive && expires == NULL && interval == NULL)
* || ('expires' and 'interval' are not both 0)
* *
* 'timerp' is a valid pointer, and *timerp == NULL * 'timerp' is a valid pointer, and *timerp == NULL
* *

View File

@ -98,6 +98,8 @@ schedule(isc_timer_t *timer, isc_time_t *now, isc_boolean_t signal_ok) {
* Note: the caller must ensure locking. * Note: the caller must ensure locking.
*/ */
REQUIRE(timer->type != isc_timertype_inactive);
/* /*
* Compute the new due time. * Compute the new due time.
*/ */
@ -190,12 +192,15 @@ destroy(isc_timer_t *timer) {
isc_timermgr_t *manager = timer->manager; isc_timermgr_t *manager = timer->manager;
/* /*
* The caller must ensure locking. * The caller must ensure it is safe to destroy the timer.
*/ */
LOCK(&manager->lock); LOCK(&manager->lock);
isc_task_purge(timer->task, timer, ISC_TASKEVENT_ANYEVENT); isc_task_purgerange(timer->task,
timer,
ISC_TASKEVENT_FIRSTEVENT,
ISC_TASKEVENT_LASTEVENT);
deschedule(timer); deschedule(timer);
UNLINK(manager->timers, timer, link); UNLINK(manager->timers, timer, link);
@ -229,7 +234,9 @@ isc_timer_create(isc_timermgr_t *manager, isc_timertype_t type,
REQUIRE(VALID_MANAGER(manager)); REQUIRE(VALID_MANAGER(manager));
REQUIRE(task != NULL); REQUIRE(task != NULL);
REQUIRE(action != NULL); REQUIRE(action != NULL);
REQUIRE(!(isc_time_isepoch(expires) && isc_interval_iszero(interval))); REQUIRE((type == isc_timertype_inactive &&
expires == NULL && interval == NULL) ||
!(isc_time_isepoch(expires) && isc_interval_iszero(interval)));
REQUIRE(timerp != NULL && *timerp == NULL); REQUIRE(timerp != NULL && *timerp == NULL);
/* /*
@ -279,7 +286,10 @@ isc_timer_create(isc_timermgr_t *manager, isc_timertype_t type,
* there are no external references to it yet. * there are no external references to it yet.
*/ */
if (type != isc_timertype_inactive)
result = schedule(timer, &now, ISC_TRUE); result = schedule(timer, &now, ISC_TRUE);
else
result = ISC_R_SUCCESS;
if (result == ISC_R_SUCCESS) if (result == ISC_R_SUCCESS)
APPEND(manager->timers, timer, link); APPEND(manager->timers, timer, link);
@ -316,7 +326,9 @@ isc_timer_reset(isc_timer_t *timer, isc_timertype_t type,
REQUIRE(VALID_TIMER(timer)); REQUIRE(VALID_TIMER(timer));
manager = timer->manager; manager = timer->manager;
REQUIRE(VALID_MANAGER(manager)); REQUIRE(VALID_MANAGER(manager));
REQUIRE(!(isc_time_isepoch(expires) && isc_interval_iszero(interval))); REQUIRE((type == isc_timertype_inactive &&
expires == NULL && interval == NULL) ||
!(isc_time_isepoch(expires) && isc_interval_iszero(interval)));
/* /*
* Get current time. * Get current time.
@ -335,7 +347,10 @@ isc_timer_reset(isc_timer_t *timer, isc_timertype_t type,
LOCK(&timer->lock); LOCK(&timer->lock);
if (purge) if (purge)
isc_task_purge(timer->task, timer, ISC_TASKEVENT_ANYEVENT); isc_task_purgerange(timer->task,
timer,
ISC_TASKEVENT_FIRSTEVENT,
ISC_TASKEVENT_LASTEVENT);
timer->type = type; timer->type = type;
timer->expires = *expires; timer->expires = *expires;
timer->interval = *interval; timer->interval = *interval;
@ -343,6 +358,10 @@ isc_timer_reset(isc_timer_t *timer, isc_timertype_t type,
isc_time_add(&now, interval, &timer->idle); isc_time_add(&now, interval, &timer->idle);
else else
isc_time_settoepoch(&timer->idle); isc_time_settoepoch(&timer->idle);
if (type == isc_timertype_inactive) {
deschedule(timer);
result = ISC_R_SUCCESS;
} else
result = schedule(timer, &now, ISC_TRUE); result = schedule(timer, &now, ISC_TRUE);
UNLOCK(&timer->lock); UNLOCK(&timer->lock);
@ -364,7 +383,14 @@ isc_timer_touch(isc_timer_t *timer) {
LOCK(&timer->lock); LOCK(&timer->lock);
INSIST(timer->type == isc_timertype_once); /*
* We'd like to
*
* REQUIRE(timer->type == isc_timertype_once);
*
* but we cannot without locking the manager lock too, which we
* don't want to do.
*/
result = isc_time_get(&now); result = isc_time_get(&now);
if (result != ISC_R_SUCCESS) { if (result != ISC_R_SUCCESS) {
@ -430,8 +456,13 @@ dispatch(isc_timermgr_t *manager, isc_time_t *now) {
isc_timer_t *timer; isc_timer_t *timer;
isc_result_t result; isc_result_t result;
/*
* The caller must be holding the manager lock.
*/
while (manager->nscheduled > 0 && !done) { while (manager->nscheduled > 0 && !done) {
timer = isc_heap_element(manager->heap, 1); timer = isc_heap_element(manager->heap, 1);
INSIST(timer->type != isc_timertype_inactive);
if (isc_time_compare(now, &timer->due) >= 0) { if (isc_time_compare(now, &timer->due) >= 0) {
if (timer->type == isc_timertype_ticker) { if (timer->type == isc_timertype_ticker) {
type = ISC_TIMEREVENT_TICK; type = ISC_TIMEREVENT_TICK;