2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-30 22:15:20 +00:00

169. [func] ratelimiter can now process N events per interval.

This commit is contained in:
Mark Andrews
2000-05-11 09:23:29 +00:00
parent 2fc337ec38
commit c052487cdf
3 changed files with 48 additions and 26 deletions

View File

@@ -1,3 +1,5 @@
169. [func] ratelimiter can now process N events per interval.
168. [bug] include statements in named.conf caused syntax errors 168. [bug] include statements in named.conf caused syntax errors
due to not consuming the semicolon ending the include due to not consuming the semicolon ending the include
statement before switching input streams. statement before switching input streams.

View File

@@ -59,6 +59,13 @@ isc_ratelimiter_setinterval(isc_ratelimiter_t *rl, isc_interval_t *interval);
* '*interval' is a nonzero interval. * '*interval' is a nonzero interval.
*/ */
void
isc_ratelimiter_setpertic(isc_ratelimiter_t *rl, isc_uint32_t perint);
/*
* Set the number of events procesed per interval timer tic.
* If 'perint' is zero it is trated as 1.
*/
isc_result_t isc_result_t
isc_ratelimiter_enqueue(isc_ratelimiter_t *rl, isc_event_t **eventp); isc_ratelimiter_enqueue(isc_ratelimiter_t *rl, isc_event_t **eventp);
/* /*

View File

@@ -36,6 +36,7 @@ struct isc_ratelimiter {
isc_task_t * task; isc_task_t * task;
isc_timer_t * timer; isc_timer_t * timer;
isc_interval_t interval; isc_interval_t interval;
isc_uint32_t pertic;
isc_ratelimiter_state_t state; isc_ratelimiter_state_t state;
isc_event_t shutdownevent; isc_event_t shutdownevent;
ISC_LIST(isc_event_t) pending; ISC_LIST(isc_event_t) pending;
@@ -69,6 +70,7 @@ isc_ratelimiter_create(isc_mem_t *mctx, isc_timermgr_t *timermgr,
rl->task = task; rl->task = task;
isc_interval_set(&rl->interval, 0, 0); isc_interval_set(&rl->interval, 0, 0);
rl->timer = NULL; rl->timer = NULL;
rl->pertic = 1;
rl->state = isc_ratelimiter_worklimited; rl->state = isc_ratelimiter_worklimited;
ISC_LIST_INIT(rl->pending); ISC_LIST_INIT(rl->pending);
@@ -111,6 +113,13 @@ isc_ratelimiter_setinterval(isc_ratelimiter_t *rl, isc_interval_t *interval) {
UNLOCK(&rl->lock); UNLOCK(&rl->lock);
return (result); return (result);
} }
void
isc_ratelimiter_setpertic(isc_ratelimiter_t *rl, isc_uint32_t pertic) {
if (pertic == 0)
pertic = 1;
rl->pertic = pertic;
}
isc_result_t isc_result_t
isc_ratelimiter_enqueue(isc_ratelimiter_t *rl, isc_event_t **eventp) { isc_ratelimiter_enqueue(isc_ratelimiter_t *rl, isc_event_t **eventp) {
@@ -142,34 +151,38 @@ ratelimiter_tick(isc_task_t *task, isc_event_t *event) {
isc_result_t result = ISC_R_SUCCESS; isc_result_t result = ISC_R_SUCCESS;
isc_ratelimiter_t *rl = (isc_ratelimiter_t *)event->ev_arg; isc_ratelimiter_t *rl = (isc_ratelimiter_t *)event->ev_arg;
isc_event_t *p; isc_event_t *p;
isc_uint32_t pertic;
UNUSED(task); UNUSED(task);
LOCK(&rl->lock);
p = ISC_LIST_HEAD(rl->pending);
if (p != NULL) {
/*
* There is work to do. Let's do it after unlocking.
*/
ISC_LIST_UNLINK(rl->pending, p, ev_link);
} else {
/*
* No work left to do. Stop the timer so that we don't
* waste resources by having it fire periodically.
*/
result = isc_timer_reset(rl->timer, isc_timertype_inactive,
NULL, NULL, ISC_FALSE);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
rl->state = isc_ratelimiter_worklimited;
}
UNLOCK(&rl->lock);
isc_event_free(&event); isc_event_free(&event);
/*
* If we have an event, dispatch it. pertic = rl->pertic;
* There is potential for optimization here since while (pertic != 0) {
* we are already executing in the context of "task". pertic--;
*/ LOCK(&rl->lock);
if (p != NULL) p = ISC_LIST_HEAD(rl->pending);
isc_task_send(rl->task, &p); if (p != NULL) {
INSIST(p == NULL); /*
* There is work to do. Let's do it after unlocking.
*/
ISC_LIST_UNLINK(rl->pending, p, ev_link);
} else {
/*
* No work left to do. Stop the timer so that we don't
* waste resources by having it fire periodically.
*/
result = isc_timer_reset(rl->timer, isc_timertype_inactive,
NULL, NULL, ISC_FALSE);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
rl->state = isc_ratelimiter_worklimited;
pertic = 0; /* Force the loop to exit. */
}
UNLOCK(&rl->lock);
if (p != NULL)
isc_task_send(rl->task, &p);
INSIST(p == NULL);
}
} }
void void