1345235Sdim/*	$NetBSD: timer_api.c,v 1.6 2020/05/25 20:47:20 christos Exp $	*/
2345235Sdim
3360658Sdim/*
4345235Sdim * Copyright (C) 2009  Internet Systems Consortium, Inc. ("ISC")
5345235Sdim *
6345235Sdim * Permission to use, copy, modify, and/or distribute this software for any
7345235Sdim * purpose with or without fee is hereby granted, provided that the above
8345235Sdim * copyright notice and this permission notice appear in all copies.
9345235Sdim *
10345235Sdim * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
11345235Sdim * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
12345235Sdim * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
13345235Sdim * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
14345235Sdim * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
15345235Sdim * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16345235Sdim * PERFORMANCE OF THIS SOFTWARE.
17345235Sdim */
18345235Sdim
19345235Sdim/* Id: timer_api.c,v 1.4 2009/09/02 23:48:02 tbox Exp  */
20345235Sdim
21345235Sdim#include <config.h>
22345235Sdim
23345235Sdim#include <unistd.h>
24345235Sdim
25345235Sdim#include <isc/app.h>
26345235Sdim#include <isc/magic.h>
27345235Sdim#include <isc/mutex.h>
28345235Sdim#include <isc/once.h>
29345235Sdim#include <isc/timer.h>
30345235Sdim#include <isc/util.h>
31345235Sdim
32345235Sdimstatic isc_mutex_t createlock;
33345235Sdimstatic isc_once_t once = ISC_ONCE_INIT;
34345235Sdimstatic isc_timermgrcreatefunc_t timermgr_createfunc = NULL;
35345235Sdim
36345235Sdimstatic void
37345235Sdiminitialize(void) {
38345235Sdim	RUNTIME_CHECK(isc_mutex_init(&createlock) == ISC_R_SUCCESS);
39345235Sdim}
40345235Sdim
41345235Sdimisc_result_t
42345235Sdimisc_timer_register(isc_timermgrcreatefunc_t createfunc) {
43345235Sdim	isc_result_t result = ISC_R_SUCCESS;
44345235Sdim
45345235Sdim	RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
46345235Sdim
47345235Sdim	LOCK(&createlock);
48345235Sdim	if (timermgr_createfunc == NULL)
49345235Sdim		timermgr_createfunc = createfunc;
50345235Sdim	else
51345235Sdim		result = ISC_R_EXISTS;
52345235Sdim	UNLOCK(&createlock);
53345235Sdim
54345235Sdim	return (result);
55345235Sdim}
56345235Sdim
57345235Sdimisc_result_t
58345235Sdimisc_timermgr_createinctx(isc_mem_t *mctx, isc_appctx_t *actx,
59345235Sdim			 isc_timermgr_t **managerp)
60345235Sdim{
61345235Sdim	isc_result_t result;
62345235Sdim
63345235Sdim	LOCK(&createlock);
64345235Sdim
65345235Sdim	REQUIRE(timermgr_createfunc != NULL);
66345235Sdim	result = (*timermgr_createfunc)(mctx, managerp);
67345235Sdim
68345235Sdim	UNLOCK(&createlock);
69345235Sdim
70345235Sdim	if (result == ISC_R_SUCCESS)
71345235Sdim		isc_appctx_settimermgr(actx, *managerp);
72345235Sdim
73345235Sdim	return (result);
74345235Sdim}
75345235Sdim
76345235Sdimisc_result_t
77345235Sdimisc_timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp) {
78345235Sdim	isc_result_t result;
79345235Sdim
80345235Sdim	LOCK(&createlock);
81345235Sdim
82345235Sdim	REQUIRE(timermgr_createfunc != NULL);
83345235Sdim	result = (*timermgr_createfunc)(mctx, managerp);
84345235Sdim
85345235Sdim	UNLOCK(&createlock);
86345235Sdim
87345235Sdim	return (result);
88345235Sdim}
89345235Sdim
90345235Sdimvoid
91345235Sdimisc_timermgr_destroy(isc_timermgr_t **managerp) {
92345235Sdim	REQUIRE(*managerp != NULL && ISCAPI_TIMERMGR_VALID(*managerp));
93345235Sdim
94345235Sdim	(*managerp)->methods->destroy(managerp);
95345235Sdim
96345235Sdim	ENSURE(*managerp == NULL);
97345235Sdim}
98345235Sdim
99345235Sdimisc_result_t
100345235Sdimisc_timer_create(isc_timermgr_t *manager, isc_timertype_t type,
101345235Sdim		 isc_time_t *expires, isc_interval_t *interval,
102345235Sdim		 isc_task_t *task, isc_taskaction_t action, const void *arg,
103345235Sdim		 isc_timer_t **timerp)
104345235Sdim{
105345235Sdim	REQUIRE(ISCAPI_TIMERMGR_VALID(manager));
106345235Sdim
107345235Sdim	return (manager->methods->timercreate(manager, type, expires,
108345235Sdim					      interval, task, action, arg,
109345235Sdim					      timerp));
110345235Sdim}
111345235Sdim
112345235Sdimvoid
113345235Sdimisc_timer_attach(isc_timer_t *timer, isc_timer_t **timerp) {
114345235Sdim	REQUIRE(ISCAPI_TIMER_VALID(timer));
115345235Sdim	REQUIRE(timerp != NULL && *timerp == NULL);
116345235Sdim
117345235Sdim	timer->methods->attach(timer, timerp);
118345235Sdim
119345235Sdim	ENSURE(*timerp == timer);
120345235Sdim}
121345235Sdim
122345235Sdimvoid
123345235Sdimisc_timer_detach(isc_timer_t **timerp) {
124345235Sdim	REQUIRE(timerp != NULL && ISCAPI_TIMER_VALID(*timerp));
125345235Sdim
126345235Sdim	(*timerp)->methods->detach(timerp);
127345235Sdim
128345235Sdim	ENSURE(*timerp == NULL);
129345235Sdim}
130345235Sdim
131345235Sdimisc_result_t
132345235Sdimisc_timer_reset(isc_timer_t *timer, isc_timertype_t type,
133345235Sdim		isc_time_t *expires, isc_interval_t *interval,
134345235Sdim		isc_boolean_t purge)
135345235Sdim{
136345235Sdim	REQUIRE(ISCAPI_TIMER_VALID(timer));
137345235Sdim
138345235Sdim	return (timer->methods->reset(timer, type, expires, interval, purge));
139345235Sdim}
140345235Sdim
141345235Sdimisc_result_t
142345235Sdimisc_timer_touch(isc_timer_t *timer) {
143345235Sdim	REQUIRE(ISCAPI_TIMER_VALID(timer));
144345235Sdim
145345235Sdim	return (timer->methods->touch(timer));
146345235Sdim}
147345235Sdim