diff options
| author | 2004-09-28 16:32:07 +0000 | |
|---|---|---|
| committer | 2004-09-28 16:32:07 +0000 | |
| commit | faa7e856a16b326b2afee3ddb8d19f2f91f85161 (patch) | |
| tree | a66b6d52d6af5dba140eb36c266ce2cc83b741f9 /usr.sbin/bind/lib/isc/timer.c | |
| parent | sync (oops) (diff) | |
| download | wireguard-openbsd-faa7e856a16b326b2afee3ddb8d19f2f91f85161.tar.xz wireguard-openbsd-faa7e856a16b326b2afee3ddb8d19f2f91f85161.zip | |
ISC BIND version 9.3.0. ok deraadt@
Diffstat (limited to 'usr.sbin/bind/lib/isc/timer.c')
| -rw-r--r-- | usr.sbin/bind/lib/isc/timer.c | 222 |
1 files changed, 139 insertions, 83 deletions
diff --git a/usr.sbin/bind/lib/isc/timer.c b/usr.sbin/bind/lib/isc/timer.c index d3cdfc4ba78..91735bd66ca 100644 --- a/usr.sbin/bind/lib/isc/timer.c +++ b/usr.sbin/bind/lib/isc/timer.c @@ -1,26 +1,27 @@ /* - * Copyright (C) 1998-2001 Internet Software Consortium. + * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 1998-2002 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM - * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL - * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING - * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION - * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. */ -/* $ISC: timer.c,v 1.64 2001/06/04 19:33:29 tale Exp $ */ +/* $ISC: timer.c,v 1.64.12.9 2004/03/08 09:04:50 marka Exp $ */ #include <config.h> #include <isc/condition.h> #include <isc/heap.h> +#include <isc/log.h> #include <isc/magic.h> #include <isc/mem.h> #include <isc/msgs.h> @@ -36,16 +37,19 @@ #endif /* ISC_PLATFORM_USETHREADS */ #ifdef ISC_TIMER_TRACE -#define XTRACE(s) printf("%s\n", (s)) -#define XTRACEID(s, t) printf("%s %p\n", (s), (t)) -#define XTRACETIME(s, d) printf("%s %u.%09u\n", (s), \ +#define XTRACE(s) fprintf(stderr, "%s\n", (s)) +#define XTRACEID(s, t) fprintf(stderr, "%s %p\n", (s), (t)) +#define XTRACETIME(s, d) fprintf(stderr, "%s %u.%09u\n", (s), \ (d).seconds, (d).nanoseconds) -#define XTRACETIMER(s, t, d) printf("%s %p %u.%09u\n", (s), (t), \ +#define XTRACETIME2(s, d, n) fprintf(stderr, "%s %u.%09u %u.%09u\n", (s), \ + (d).seconds, (d).nanoseconds, (n).seconds, (n).nanoseconds) +#define XTRACETIMER(s, t, d) fprintf(stderr, "%s %p %u.%09u\n", (s), (t), \ (d).seconds, (d).nanoseconds) #else #define XTRACE(s) #define XTRACEID(s, t) #define XTRACETIME(s, d) +#define XTRACETIME2(s, d, n) #define XTRACETIMER(s, t, d) #endif /* ISC_TIMER_TRACE */ @@ -107,6 +111,9 @@ schedule(isc_timer_t *timer, isc_time_t *now, isc_boolean_t signal_ok) { isc_timermgr_t *manager; isc_time_t due; int cmp; +#ifdef ISC_PLATFORM_USETHREADS + isc_boolean_t timedwait; +#endif /* * Note: the caller must ensure locking. @@ -118,13 +125,27 @@ schedule(isc_timer_t *timer, isc_time_t *now, isc_boolean_t signal_ok) { UNUSED(signal_ok); #endif /* ISC_PLATFORM_USETHREADS */ + manager = timer->manager; + +#ifdef ISC_PLATFORM_USETHREADS + /* + * If the manager was timed wait, we may need to signal the + * manager to force a wakeup. + */ + timedwait = ISC_TF(manager->nscheduled > 0 && + isc_time_seconds(&manager->due) != 0); +#endif + /* * Compute the new due time. */ - if (timer->type == isc_timertype_ticker) { + if (timer->type != isc_timertype_once) { result = isc_time_add(now, &timer->interval, &due); if (result != ISC_R_SUCCESS) return (result); + if (timer->type == isc_timertype_limited && + isc_time_compare(&timer->expires, &due) < 0) + due = timer->expires; } else { if (isc_time_isepoch(&timer->idle)) due = timer->expires; @@ -139,7 +160,7 @@ schedule(isc_timer_t *timer, isc_time_t *now, isc_boolean_t signal_ok) { /* * Schedule the timer. */ - manager = timer->manager; + if (timer->index > 0) { /* * Already scheduled. @@ -177,6 +198,31 @@ schedule(isc_timer_t *timer, isc_time_t *now, isc_boolean_t signal_ok) { * run thread, or explicitly setting the value in the manager. */ #ifdef ISC_PLATFORM_USETHREADS + + /* + * This is a temporary (probably) hack to fix a bug on tru64 5.1 + * and 5.1a. Sometimes, pthread_cond_timedwait() doesn't actually + * return when the time expires, so here, we check to see if + * we're 15 seconds or more behind, and if we are, we signal + * the dispatcher. This isn't such a bad idea as a general purpose + * watchdog, so perhaps we should just leave it in here. + */ + if (signal_ok && timedwait) { + isc_interval_t fifteen; + isc_time_t then; + + isc_interval_set(&fifteen, 15, 0); + isc_time_add(&manager->due, &fifteen, &then); + + if (isc_time_compare(&then, now) < 0) { + SIGNAL(&manager->wakeup); + signal_ok = ISC_FALSE; + isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, + ISC_LOGMODULE_TIMER, ISC_LOG_WARNING, + "*** POKED TIMER ***"); + } + } + if (timer->index == 1 && signal_ok) { XTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_TIMER, ISC_MSG_SIGNALSCHED, @@ -230,11 +276,11 @@ destroy(isc_timer_t *timer) { LOCK(&manager->lock); - isc_task_purgerange(timer->task, - timer, - ISC_TIMEREVENT_FIRSTEVENT, - ISC_TIMEREVENT_LASTEVENT, - NULL); + (void)isc_task_purgerange(timer->task, + timer, + ISC_TIMEREVENT_FIRSTEVENT, + ISC_TIMEREVENT_LASTEVENT, + NULL); deschedule(timer); UNLINK(manager->timers, timer, link); @@ -243,7 +289,7 @@ destroy(isc_timer_t *timer) { isc_task_detach(&timer->task); DESTROYLOCK(&timer->lock); timer->magic = 0; - isc_mem_put(manager->mctx, timer, sizeof *timer); + isc_mem_put(manager->mctx, timer, sizeof(*timer)); } isc_result_t @@ -274,22 +320,14 @@ isc_timer_create(isc_timermgr_t *manager, isc_timertype_t type, REQUIRE(type == isc_timertype_inactive || !(isc_time_isepoch(expires) && isc_interval_iszero(interval))); REQUIRE(timerp != NULL && *timerp == NULL); + REQUIRE(type != isc_timertype_limited || + !(isc_time_isepoch(expires) || isc_interval_iszero(interval))); /* * Get current time. */ if (type != isc_timertype_inactive) { - result = isc_time_now(&now); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_time_now() %s: %s", - isc_msgcat_get(isc_msgcat, - ISC_MSGSET_GENERAL, - ISC_MSG_FAILED, - "failed"), - isc_result_totext(result)); - return (ISC_R_UNEXPECTED); - } + TIME_NOW(&now); } else { /* * We don't have to do this, but it keeps the compiler from @@ -300,7 +338,7 @@ isc_timer_create(isc_timermgr_t *manager, isc_timertype_t type, } - timer = isc_mem_get(manager->mctx, sizeof *timer); + timer = isc_mem_get(manager->mctx, sizeof(*timer)); if (timer == NULL) return (ISC_R_NOMEMORY); @@ -334,7 +372,7 @@ isc_timer_create(isc_timermgr_t *manager, isc_timertype_t type, timer->index = 0; if (isc_mutex_init(&timer->lock) != ISC_R_SUCCESS) { isc_task_detach(&timer->task); - isc_mem_put(manager->mctx, timer, sizeof *timer); + isc_mem_put(manager->mctx, timer, sizeof(*timer)); UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_mutex_init() %s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, @@ -364,7 +402,7 @@ isc_timer_create(isc_timermgr_t *manager, isc_timertype_t type, timer->magic = 0; DESTROYLOCK(&timer->lock); isc_task_detach(&timer->task); - isc_mem_put(manager->mctx, timer, sizeof *timer); + isc_mem_put(manager->mctx, timer, sizeof(*timer)); return (result); } @@ -397,22 +435,14 @@ isc_timer_reset(isc_timer_t *timer, isc_timertype_t type, interval = isc_interval_zero; REQUIRE(type == isc_timertype_inactive || !(isc_time_isepoch(expires) && isc_interval_iszero(interval))); + REQUIRE(type != isc_timertype_limited || + !(isc_time_isepoch(expires) || isc_interval_iszero(interval))); /* * Get current time. */ if (type != isc_timertype_inactive) { - result = isc_time_now(&now); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_time_now() %s: %s", - isc_msgcat_get(isc_msgcat, - ISC_MSGSET_GENERAL, - ISC_MSG_FAILED, - "failed"), - isc_result_totext(result)); - return (ISC_R_UNEXPECTED); - } + TIME_NOW(&now); } else { /* * We don't have to do this, but it keeps the compiler from @@ -428,11 +458,11 @@ isc_timer_reset(isc_timer_t *timer, isc_timertype_t type, LOCK(&timer->lock); if (purge) - isc_task_purgerange(timer->task, - timer, - ISC_TIMEREVENT_FIRSTEVENT, - ISC_TIMEREVENT_LASTEVENT, - NULL); + (void)isc_task_purgerange(timer->task, + timer, + ISC_TIMEREVENT_FIRSTEVENT, + ISC_TIMEREVENT_LASTEVENT, + NULL); timer->type = type; timer->expires = *expires; timer->interval = *interval; @@ -458,6 +488,19 @@ isc_timer_reset(isc_timer_t *timer, isc_timertype_t type, } isc_result_t +isc_timer_gettype(isc_timer_t *timer) { + isc_timertype_t t; + + REQUIRE(VALID_TIMER(timer)); + + LOCK(&timer->lock); + t = timer->type; + UNLOCK(&timer->lock); + + return (t); +} + +isc_result_t isc_timer_touch(isc_timer_t *timer) { isc_result_t result; isc_time_t now; @@ -479,16 +522,8 @@ isc_timer_touch(isc_timer_t *timer) { * don't want to do. */ - result = isc_time_now(&now); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_time_now() %s: %s", - isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, - ISC_MSG_FAILED, "failed"), - isc_result_totext(result)); - result = ISC_R_UNEXPECTED; - } else - result = isc_time_add(&now, &timer->interval, &timer->idle); + TIME_NOW(&now); + result = isc_time_add(&now, &timer->interval, &timer->idle); UNLOCK(&timer->lock); @@ -557,6 +592,18 @@ dispatch(isc_timermgr_t *manager, isc_time_t *now) { type = ISC_TIMEREVENT_TICK; post_event = ISC_TRUE; need_schedule = ISC_TRUE; + } else if (timer->type == isc_timertype_limited) { + int cmp; + cmp = isc_time_compare(now, &timer->expires); + if (cmp >= 0) { + type = ISC_TIMEREVENT_LIFE; + post_event = ISC_TRUE; + need_schedule = ISC_FALSE; + } else { + type = ISC_TIMEREVENT_TICK; + post_event = ISC_TRUE; + need_schedule = ISC_TRUE; + } } else if (!isc_time_isepoch(&timer->expires) && isc_time_compare(now, &timer->expires) >= 0) { @@ -595,7 +642,7 @@ dispatch(isc_timermgr_t *manager, isc_time_t *now) { type, timer->action, timer->arg, - sizeof *event); + sizeof(*event)); if (event != NULL) isc_task_send(timer->task, &event); @@ -642,7 +689,7 @@ run(void *uap) { LOCK(&manager->lock); while (!manager->done) { - RUNTIME_CHECK(isc_time_now(&now) == ISC_R_SUCCESS); + TIME_NOW(&now); XTRACETIME(isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_RUNNING, @@ -651,18 +698,17 @@ run(void *uap) { dispatch(manager, &now); if (manager->nscheduled > 0) { - XTRACETIME(isc_msgcat_get(isc_msgcat, - ISC_MSGSET_GENERAL, - ISC_MSG_WAITUNTIL, - "waituntil"), - manager->due); - result = WAITUNTIL(&manager->wakeup, &manager->lock, - &manager->due); + XTRACETIME2(isc_msgcat_get(isc_msgcat, + ISC_MSGSET_GENERAL, + ISC_MSG_WAITUNTIL, + "waituntil"), + manager->due, now); + result = WAITUNTIL(&manager->wakeup, &manager->lock, &manager->due); INSIST(result == ISC_R_SUCCESS || result == ISC_R_TIMEDOUT); } else { - XTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, - ISC_MSG_WAIT, "wait")); + XTRACETIME(isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, + ISC_MSG_WAIT, "wait"), now); WAIT(&manager->wakeup, &manager->lock); } XTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_TIMER, @@ -717,7 +763,7 @@ isc_timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp) { } #endif /* ISC_PLATFORM_USETHREADS */ - manager = isc_mem_get(mctx, sizeof *manager); + manager = isc_mem_get(mctx, sizeof(*manager)); if (manager == NULL) return (ISC_R_NOMEMORY); @@ -731,12 +777,12 @@ isc_timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp) { result = isc_heap_create(mctx, sooner, set_index, 0, &manager->heap); if (result != ISC_R_SUCCESS) { INSIST(result == ISC_R_NOMEMORY); - isc_mem_put(mctx, manager, sizeof *manager); + isc_mem_put(mctx, manager, sizeof(*manager)); return (ISC_R_NOMEMORY); } if (isc_mutex_init(&manager->lock) != ISC_R_SUCCESS) { isc_heap_destroy(&manager->heap); - isc_mem_put(mctx, manager, sizeof *manager); + isc_mem_put(mctx, manager, sizeof(*manager)); UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_mutex_init() %s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, @@ -749,7 +795,7 @@ isc_timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp) { isc_mem_detach(&manager->mctx); DESTROYLOCK(&manager->lock); isc_heap_destroy(&manager->heap); - isc_mem_put(mctx, manager, sizeof *manager); + isc_mem_put(mctx, manager, sizeof(*manager)); UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_condition_init() %s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, @@ -762,7 +808,7 @@ isc_timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp) { (void)isc_condition_destroy(&manager->wakeup); DESTROYLOCK(&manager->lock); isc_heap_destroy(&manager->heap); - isc_mem_put(mctx, manager, sizeof *manager); + isc_mem_put(mctx, manager, sizeof(*manager)); UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_thread_create() %s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, @@ -780,6 +826,17 @@ isc_timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp) { } void +isc_timermgr_poke(isc_timermgr_t *manager) { +#ifdef ISC_PLATFORM_USETHREADS + REQUIRE(VALID_MANAGER(manager)); + + SIGNAL(&manager->wakeup); +#else + UNUSED(manager); +#endif +} + +void isc_timermgr_destroy(isc_timermgr_t **managerp) { isc_timermgr_t *manager; isc_mem_t *mctx; @@ -837,7 +894,7 @@ isc_timermgr_destroy(isc_timermgr_t **managerp) { isc_heap_destroy(&manager->heap); manager->magic = 0; mctx = manager->mctx; - isc_mem_put(mctx, manager, sizeof *manager); + isc_mem_put(mctx, manager, sizeof(*manager)); isc_mem_detach(&mctx); *managerp = NULL; @@ -852,13 +909,12 @@ isc__timermgr_nextevent(isc_time_t *when) { return (ISC_R_SUCCESS); } -isc_result_t +void isc__timermgr_dispatch(void) { isc_time_t now; if (timermgr == NULL) - return (ISC_R_NOTFOUND); - isc_time_now(&now); + return; + TIME_NOW(&now); dispatch(timermgr, &now); - return (ISC_R_SUCCESS); } #endif /* ISC_PLATFORM_USETHREADS */ |
