mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-30 05:57:52 +00:00
allow timer to be inactive; use isc_task_purgerange
This commit is contained in:
parent
d6b0e99380
commit
d13284da19
@ -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_TICK (ISC_EVENTCLASS_TIMER + 1)
|
#define ISC_TIMEREVENT_FIRSTEVENT (ISC_EVENTCLASS_TIMER + 0)
|
||||||
#define ISC_TIMEREVENT_IDLE (ISC_EVENTCLASS_TIMER + 2)
|
#define ISC_TIMEREVENT_TICK (ISC_EVENTCLASS_TIMER + 1)
|
||||||
#define ISC_TIMEREVENT_LIFE (ISC_EVENTCLASS_TIMER + 3)
|
#define ISC_TIMEREVENT_IDLE (ISC_EVENTCLASS_TIMER + 2)
|
||||||
|
#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
|
||||||
*
|
*
|
||||||
|
@ -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.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
result = schedule(timer, &now, ISC_TRUE);
|
if (type != isc_timertype_inactive)
|
||||||
|
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,7 +358,11 @@ 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);
|
||||||
result = schedule(timer, &now, ISC_TRUE);
|
if (type == isc_timertype_inactive) {
|
||||||
|
deschedule(timer);
|
||||||
|
result = ISC_R_SUCCESS;
|
||||||
|
} else
|
||||||
|
result = schedule(timer, &now, ISC_TRUE);
|
||||||
|
|
||||||
UNLOCK(&timer->lock);
|
UNLOCK(&timer->lock);
|
||||||
UNLOCK(&manager->lock);
|
UNLOCK(&manager->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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user