* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: ratelimiter.h,v 1.13 2001/01/09 21:57:24 bwelling Exp $ */
+/* $Id: ratelimiter.h,v 1.14 2002/07/26 06:42:01 marka Exp $ */
#ifndef ISC_RATELIMITER_H
#define ISC_RATELIMITER_H 1
* Detach from a rate limiter.
*/
+isc_result_t
+isc_ratelimiter_stall(isc_ratelimiter_t *rl);
+/*
+ * Stall event processing.
+ */
+
+isc_result_t
+isc_ratelimiter_release(isc_ratelimiter_t *rl);
+/*
+ * Release a stalled rate limiter.
+ */
+
ISC_LANG_ENDDECLS
#endif /* ISC_RATELIMITER_H */
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: ratelimiter.c,v 1.18 2001/01/09 21:56:23 bwelling Exp $ */
+/* $Id: ratelimiter.c,v 1.19 2002/07/26 06:42:01 marka Exp $ */
#include <config.h>
#include <isc/util.h>
typedef enum {
+ isc_ratelimiter_stalled,
isc_ratelimiter_ratelimited,
isc_ratelimiter_worklimited,
isc_ratelimiter_shuttingdown
REQUIRE(ev->ev_sender == NULL);
LOCK(&rl->lock);
- if (rl->state == isc_ratelimiter_ratelimited) {
+ if (rl->state == isc_ratelimiter_ratelimited ||
+ rl->state == isc_ratelimiter_stalled) {
isc_event_t *ev = *eventp;
ev->ev_sender = task;
ISC_LIST_APPEND(rl->pending, ev, ev_link);
*rlp = NULL;
}
+isc_result_t
+isc_ratelimiter_stall(isc_ratelimiter_t *rl) {
+ isc_result_t result = ISC_R_SUCCESS;
+
+ LOCK(&rl->lock);
+ switch (rl->state) {
+ case isc_ratelimiter_shuttingdown:
+ result = ISC_R_SHUTTINGDOWN;
+ break;
+ case isc_ratelimiter_ratelimited:
+ result = isc_timer_reset(rl->timer, isc_timertype_inactive,
+ NULL, NULL, ISC_FALSE);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ case isc_ratelimiter_worklimited:
+ case isc_ratelimiter_stalled:
+ rl->state = isc_ratelimiter_stalled;
+ break;
+ }
+ UNLOCK(&rl->lock);
+ return (result);
+}
+
+isc_result_t
+isc_ratelimiter_release(isc_ratelimiter_t *rl) {
+ isc_result_t result = ISC_R_SUCCESS;
+
+ LOCK(&rl->lock);
+ switch (rl->state) {
+ case isc_ratelimiter_shuttingdown:
+ result = ISC_R_SHUTTINGDOWN;
+ break;
+ case isc_ratelimiter_stalled:
+ if (!ISC_LIST_EMPTY(rl->pending)) {
+ result = isc_timer_reset(rl->timer,
+ isc_timertype_ticker, NULL,
+ &rl->interval, ISC_FALSE);
+ if (result == ISC_R_SUCCESS)
+ rl->state = isc_ratelimiter_ratelimited;
+ } else
+ rl->state = isc_ratelimiter_worklimited;
+ break;
+ case isc_ratelimiter_ratelimited:
+ case isc_ratelimiter_worklimited:
+ break;
+ }
+ UNLOCK(&rl->lock);
+ return (result);
+}