mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-28 04:34:54 -04:00
Allow the timer code to run without threads.
This commit is contained in:
parent
352cb92ac2
commit
8ec174ad4e
2 changed files with 116 additions and 6 deletions
|
|
@ -15,19 +15,24 @@
|
|||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: timer.c,v 1.55 2000/08/26 01:42:29 bwelling Exp $ */
|
||||
/* $Id: timer.c,v 1.56 2000/08/29 21:30:02 bwelling Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <isc/condition.h>
|
||||
#include <isc/heap.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/platform.h>
|
||||
#include <isc/task.h>
|
||||
#include <isc/thread.h>
|
||||
#include <isc/time.h>
|
||||
#include <isc/timer.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
#ifndef ISC_PLATFORM_USETHREADS
|
||||
#include "timer_p.h"
|
||||
#endif
|
||||
|
||||
#ifdef ISC_TIMER_TRACE
|
||||
#define XTRACE(s) printf("%s\n", (s))
|
||||
#define XTRACEID(s, t) printf("%s %p\n", (s), (t))
|
||||
|
|
@ -80,11 +85,22 @@ struct isc_timermgr {
|
|||
LIST(isc_timer_t) timers;
|
||||
unsigned int nscheduled;
|
||||
isc_time_t due;
|
||||
#ifdef ISC_PLATFORM_USETHREADS
|
||||
isc_condition_t wakeup;
|
||||
isc_thread_t thread;
|
||||
#else
|
||||
unsigned int refs;
|
||||
#endif
|
||||
isc_heap_t * heap;
|
||||
};
|
||||
|
||||
#ifndef ISC_PLATFORM_USETHREADS
|
||||
/*
|
||||
* If threads are not in use, there can be only one.
|
||||
*/
|
||||
static isc_timermgr_t *timermgr = NULL;
|
||||
#endif
|
||||
|
||||
static inline isc_result_t
|
||||
schedule(isc_timer_t *timer, isc_time_t *now, isc_boolean_t signal_ok) {
|
||||
isc_result_t result;
|
||||
|
|
@ -98,6 +114,10 @@ schedule(isc_timer_t *timer, isc_time_t *now, isc_boolean_t signal_ok) {
|
|||
|
||||
REQUIRE(timer->type != isc_timertype_inactive);
|
||||
|
||||
#ifndef ISC_PLATFORM_USETHREADS
|
||||
UNUSED(signal_ok);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Compute the new due time.
|
||||
*/
|
||||
|
|
@ -150,15 +170,21 @@ schedule(isc_timer_t *timer, isc_time_t *now, isc_boolean_t signal_ok) {
|
|||
XTRACETIMER("schedule", timer, due);
|
||||
|
||||
/*
|
||||
* If this timer is at the head of the queue, we wake up the run
|
||||
* thread. We do this, because we likely have set a more recent
|
||||
* due time than the one the run thread is sleeping on, and we don't
|
||||
* want it to oversleep.
|
||||
* If this timer is at the head of the queue, we need to ensure
|
||||
* that we won't miss it if it has a more recent due time than
|
||||
* the current "next" timer. We do this either by waking up the
|
||||
* run thread, or explicitly setting the value in the manager.
|
||||
*/
|
||||
#ifdef ISC_PLATFORM_USETHREADS
|
||||
if (timer->index == 1 && signal_ok) {
|
||||
XTRACE("signal (schedule)");
|
||||
SIGNAL(&manager->wakeup);
|
||||
}
|
||||
#else
|
||||
if (timer->index == 1 &&
|
||||
isc_time_compare(&timer->due, &manager->due) < 0)
|
||||
manager->due = timer->due;
|
||||
#endif
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
|
@ -180,10 +206,12 @@ deschedule(isc_timer_t *timer) {
|
|||
timer->index = 0;
|
||||
INSIST(manager->nscheduled > 0);
|
||||
manager->nscheduled--;
|
||||
#ifdef ISC_PLATFORM_USETHREADS
|
||||
if (need_wakeup) {
|
||||
XTRACE("signal (deschedule)");
|
||||
SIGNAL(&manager->wakeup);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -569,6 +597,7 @@ dispatch(isc_timermgr_t *manager, isc_time_t *now) {
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef ISC_PLATFORM_USETHREADS
|
||||
static isc_threadresult_t
|
||||
#ifdef _WIN32 /* XXXDCL */
|
||||
WINAPI
|
||||
|
|
@ -602,6 +631,7 @@ run(void *uap) {
|
|||
|
||||
return ((isc_threadresult_t)0);
|
||||
}
|
||||
#endif
|
||||
|
||||
static isc_boolean_t
|
||||
sooner(void *v1, void *v2) {
|
||||
|
|
@ -638,6 +668,14 @@ isc_timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp) {
|
|||
|
||||
REQUIRE(managerp != NULL && *managerp == NULL);
|
||||
|
||||
#ifndef ISC_PLATFORM_USETHREADS
|
||||
if (timermgr != NULL) {
|
||||
timermgr->refs++;
|
||||
*managerp = timermgr;
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
#endif
|
||||
|
||||
manager = isc_mem_get(mctx, sizeof *manager);
|
||||
if (manager == NULL)
|
||||
return (ISC_R_NOMEMORY);
|
||||
|
|
@ -662,7 +700,10 @@ isc_timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp) {
|
|||
"isc_mutex_init() failed");
|
||||
return (ISC_R_UNEXPECTED);
|
||||
}
|
||||
isc_mem_attach(mctx, &manager->mctx);
|
||||
#ifdef ISC_PLATFORM_USETHREADS
|
||||
if (isc_condition_init(&manager->wakeup) != ISC_R_SUCCESS) {
|
||||
isc_mem_detach(&manager->mctx);
|
||||
DESTROYLOCK(&manager->lock);
|
||||
isc_heap_destroy(&manager->heap);
|
||||
isc_mem_put(mctx, manager, sizeof *manager);
|
||||
|
|
@ -670,7 +711,6 @@ isc_timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp) {
|
|||
"isc_condition_init() failed");
|
||||
return (ISC_R_UNEXPECTED);
|
||||
}
|
||||
isc_mem_attach(mctx, &manager->mctx);
|
||||
if (isc_thread_create(run, manager, &manager->thread) !=
|
||||
ISC_R_SUCCESS) {
|
||||
isc_mem_detach(&manager->mctx);
|
||||
|
|
@ -682,6 +722,10 @@ isc_timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp) {
|
|||
"isc_thread_create() failed");
|
||||
return (ISC_R_UNEXPECTED);
|
||||
}
|
||||
#else
|
||||
manager->refs = 1;
|
||||
timermgr = manager;
|
||||
#endif
|
||||
|
||||
*managerp = manager;
|
||||
|
||||
|
|
@ -703,25 +747,42 @@ isc_timermgr_destroy(isc_timermgr_t **managerp) {
|
|||
|
||||
LOCK(&manager->lock);
|
||||
|
||||
#ifndef ISC_PLATFORM_USETHREADS
|
||||
if (manager->refs > 1) {
|
||||
manager->refs--;
|
||||
UNLOCK(&manager->lock);
|
||||
*managerp = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
isc__timermgr_dispatch();
|
||||
#endif
|
||||
|
||||
REQUIRE(EMPTY(manager->timers));
|
||||
manager->done = ISC_TRUE;
|
||||
|
||||
#ifdef ISC_PLATFORM_USETHREADS
|
||||
XTRACE("signal (destroy)");
|
||||
SIGNAL(&manager->wakeup);
|
||||
#endif
|
||||
|
||||
UNLOCK(&manager->lock);
|
||||
|
||||
#ifdef ISC_PLATFORM_USETHREADS
|
||||
/*
|
||||
* Wait for thread to exit.
|
||||
*/
|
||||
if (isc_thread_join(manager->thread, NULL) != ISC_R_SUCCESS)
|
||||
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
||||
"isc_thread_join() failed");
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Clean up.
|
||||
*/
|
||||
#ifdef ISC_PLATFORM_USETHREADS
|
||||
(void)isc_condition_destroy(&manager->wakeup);
|
||||
#endif
|
||||
DESTROYLOCK(&manager->lock);
|
||||
isc_heap_destroy(&manager->heap);
|
||||
manager->magic = 0;
|
||||
|
|
@ -731,3 +792,23 @@ isc_timermgr_destroy(isc_timermgr_t **managerp) {
|
|||
|
||||
*managerp = NULL;
|
||||
}
|
||||
|
||||
#ifndef ISC_PLATFORM_USETHREADS
|
||||
isc_result_t
|
||||
isc__timermgr_nextevent(isc_time_t *when) {
|
||||
if (timermgr == NULL || timermgr->nscheduled == 0)
|
||||
return (ISC_R_NOTFOUND);
|
||||
*when = timermgr->due;
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc__timermgr_dispatch(void) {
|
||||
isc_time_t now;
|
||||
if (timermgr == NULL)
|
||||
return (ISC_R_NOTFOUND);
|
||||
isc_time_now(&now);
|
||||
dispatch(timermgr, &now);
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
29
lib/isc/timer_p.h
Normal file
29
lib/isc/timer_p.h
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (C) 2000 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.
|
||||
*/
|
||||
|
||||
/* $Id: timer_p.h,v 1.1 2000/08/29 21:30:03 bwelling Exp $ */
|
||||
|
||||
#ifndef ISC_TIMER_P_H
|
||||
#define ISC_TIMER_P_H
|
||||
|
||||
isc_result_t
|
||||
isc__timermgr_nextevent(isc_time_t *when);
|
||||
|
||||
isc_result_t
|
||||
isc__timermgr_dispatch(void);
|
||||
|
||||
#endif /* ISC_TIMER_P_H */
|
||||
Loading…
Reference in a new issue