1258945Sroberto/*
2280849Scy * Copyright (C) 2004-2007, 2009  Internet Systems Consortium, Inc. ("ISC")
3258945Sroberto * Copyright (C) 1999-2001  Internet Software Consortium.
4258945Sroberto *
5258945Sroberto * Permission to use, copy, modify, and/or distribute this software for any
6258945Sroberto * purpose with or without fee is hereby granted, provided that the above
7258945Sroberto * copyright notice and this permission notice appear in all copies.
8258945Sroberto *
9258945Sroberto * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10258945Sroberto * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11258945Sroberto * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12258945Sroberto * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13258945Sroberto * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14258945Sroberto * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15258945Sroberto * PERFORMANCE OF THIS SOFTWARE.
16258945Sroberto */
17258945Sroberto
18280849Scy/* $Id: app.h,v 1.11 2009/09/02 23:48:03 tbox Exp $ */
19258945Sroberto
20258945Sroberto#ifndef ISC_APP_H
21258945Sroberto#define ISC_APP_H 1
22258945Sroberto
23258945Sroberto/*****
24258945Sroberto ***** Module Info
25258945Sroberto *****/
26258945Sroberto
27258945Sroberto/*! \file isc/app.h
28258945Sroberto * \brief ISC Application Support
29258945Sroberto *
30258945Sroberto * Dealing with program termination can be difficult, especially in a
31258945Sroberto * multithreaded program.  The routines in this module help coordinate
32258945Sroberto * the shutdown process.  They are used as follows by the initial (main)
33258945Sroberto * thread of the application:
34258945Sroberto *
35258945Sroberto *\li		isc_app_start();	Call very early in main(), before
36258945Sroberto *					any other threads have been created.
37258945Sroberto *
38258945Sroberto *\li		isc_app_run();		This will post any on-run events,
39258945Sroberto *					and then block until application
40258945Sroberto *					shutdown is requested.  A shutdown
41258945Sroberto *					request is made by calling
42258945Sroberto *					isc_app_shutdown(), or by sending
43258945Sroberto *					SIGINT or SIGTERM to the process.
44258945Sroberto *					After isc_app_run() returns, the
45258945Sroberto *					application should shutdown itself.
46258945Sroberto *
47258945Sroberto *\li		isc_app_finish();	Call very late in main().
48258945Sroberto *
49258945Sroberto * Applications that want to use SIGHUP/isc_app_reload() to trigger reloading
50258945Sroberto * should check the result of isc_app_run() and call the reload routine if
51258945Sroberto * the result is ISC_R_RELOAD.  They should then call isc_app_run() again
52258945Sroberto * to resume waiting for reload or termination.
53258945Sroberto *
54258945Sroberto * Use of this module is not required.  In particular, isc_app_start() is
55258945Sroberto * NOT an ISC library initialization routine.
56258945Sroberto *
57280849Scy * This module also supports per-thread 'application contexts'.  With this
58280849Scy * mode, a thread-based application will have a separate context, in which
59280849Scy * it uses other ISC library services such as tasks or timers.  Signals are
60280849Scy * not caught in this mode, so that the application can handle the signals
61280849Scy * in its preferred way.
62280849Scy *
63258945Sroberto * \li MP:
64258945Sroberto *	Clients must ensure that isc_app_start(), isc_app_run(), and
65258945Sroberto *	isc_app_finish() are called at most once.  isc_app_shutdown()
66258945Sroberto *	is safe to use by any thread (provided isc_app_start() has been
67258945Sroberto *	called previously).
68258945Sroberto *
69280849Scy *	The same note applies to isc_app_ctxXXX() functions, but in this case
70280849Scy *	it's a per-thread restriction.  For example, a thread with an
71280849Scy *	application context must ensure that isc_app_ctxstart() with the
72280849Scy *	context is called at most once.
73280849Scy *
74258945Sroberto * \li Reliability:
75258945Sroberto *	No anticipated impact.
76258945Sroberto *
77258945Sroberto * \li Resources:
78258945Sroberto *	None.
79258945Sroberto *
80258945Sroberto * \li Security:
81258945Sroberto *	No anticipated impact.
82258945Sroberto *
83258945Sroberto * \li Standards:
84258945Sroberto *	None.
85258945Sroberto */
86258945Sroberto
87258945Sroberto#include <isc/eventclass.h>
88258945Sroberto#include <isc/lang.h>
89280849Scy#include <isc/magic.h>
90258945Sroberto#include <isc/result.h>
91258945Sroberto
92280849Scy/***
93280849Scy *** Types
94280849Scy ***/
95280849Scy
96258945Srobertotypedef isc_event_t isc_appevent_t;
97258945Sroberto
98258945Sroberto#define ISC_APPEVENT_FIRSTEVENT		(ISC_EVENTCLASS_APP + 0)
99258945Sroberto#define ISC_APPEVENT_SHUTDOWN		(ISC_EVENTCLASS_APP + 1)
100258945Sroberto#define ISC_APPEVENT_LASTEVENT		(ISC_EVENTCLASS_APP + 65535)
101258945Sroberto
102280849Scy/*%
103280849Scy * app module methods.  Only app driver implementations use this structure.
104280849Scy * Other clients should use the top-level interfaces (i.e., isc_app_xxx
105280849Scy * functions).  magic must be ISCAPI_APPMETHODS_MAGIC.
106280849Scy */
107280849Scytypedef struct isc_appmethods {
108280849Scy	void		(*ctxdestroy)(isc_appctx_t **ctxp);
109280849Scy	isc_result_t	(*ctxstart)(isc_appctx_t *ctx);
110280849Scy	isc_result_t	(*ctxrun)(isc_appctx_t *ctx);
111280849Scy	isc_result_t	(*ctxsuspend)(isc_appctx_t *ctx);
112280849Scy	isc_result_t	(*ctxshutdown)(isc_appctx_t *ctx);
113280849Scy	void		(*ctxfinish)(isc_appctx_t *ctx);
114280849Scy	void		(*settaskmgr)(isc_appctx_t *ctx,
115280849Scy				      isc_taskmgr_t *timermgr);
116280849Scy	void		(*setsocketmgr)(isc_appctx_t *ctx,
117280849Scy					isc_socketmgr_t *timermgr);
118280849Scy	void		(*settimermgr)(isc_appctx_t *ctx,
119280849Scy				       isc_timermgr_t *timermgr);
120280849Scy} isc_appmethods_t;
121280849Scy
122280849Scy/*%
123280849Scy * This structure is actually just the common prefix of an application context
124280849Scy * implementation's version of an isc_appctx_t.
125280849Scy * \brief
126280849Scy * Direct use of this structure by clients is forbidden.  app implementations
127280849Scy * may change the structure.  'magic' must be ISCAPI_APPCTX_MAGIC for any
128280849Scy * of the isc_app_ routines to work.  app implementations must maintain
129280849Scy * all app context invariants.
130280849Scy */
131280849Scystruct isc_appctx {
132280849Scy	unsigned int		impmagic;
133280849Scy	unsigned int		magic;
134280849Scy	isc_appmethods_t	*methods;
135280849Scy};
136280849Scy
137280849Scy#define ISCAPI_APPCTX_MAGIC		ISC_MAGIC('A','a','p','c')
138280849Scy#define ISCAPI_APPCTX_VALID(c)		((c) != NULL && \
139280849Scy					 (c)->magic == ISCAPI_APPCTX_MAGIC)
140280849Scy
141258945SrobertoISC_LANG_BEGINDECLS
142258945Sroberto
143258945Srobertoisc_result_t
144280849Scyisc_app_ctxstart(isc_appctx_t *ctx);
145280849Scy
146280849Scyisc_result_t
147258945Srobertoisc_app_start(void);
148258945Sroberto/*!<
149258945Sroberto * \brief Start an ISC library application.
150258945Sroberto *
151258945Sroberto * Notes:
152258945Sroberto *	This call should be made before any other ISC library call, and as
153258945Sroberto *	close to the beginning of the application as possible.
154280849Scy *
155280849Scy * Requires:
156280849Scy *	'ctx' is a valid application context (for app_ctxstart()).
157258945Sroberto */
158258945Sroberto
159258945Srobertoisc_result_t
160258945Srobertoisc_app_onrun(isc_mem_t *mctx, isc_task_t *task, isc_taskaction_t action,
161258945Sroberto	      void *arg);
162258945Sroberto/*!<
163258945Sroberto * \brief Request delivery of an event when the application is run.
164258945Sroberto *
165258945Sroberto * Requires:
166280849Scy *\li	isc_app_start() has been called.
167258945Sroberto *
168258945Sroberto * Returns:
169258945Sroberto *	ISC_R_SUCCESS
170258945Sroberto *	ISC_R_NOMEMORY
171258945Sroberto */
172258945Sroberto
173258945Srobertoisc_result_t
174280849Scyisc_app_ctxrun(isc_appctx_t *ctx);
175280849Scy
176280849Scyisc_result_t
177258945Srobertoisc_app_run(void);
178258945Sroberto/*!<
179258945Sroberto * \brief Run an ISC library application.
180258945Sroberto *
181258945Sroberto * Notes:
182258945Sroberto *\li	The caller (typically the initial thread of an application) will
183258945Sroberto *	block until shutdown is requested.  When the call returns, the
184258945Sroberto *	caller should start shutting down the application.
185258945Sroberto *
186258945Sroberto * Requires:
187280849Scy *\li	isc_app_[ctx]start() has been called.
188258945Sroberto *
189258945Sroberto * Ensures:
190258945Sroberto *\li	Any events requested via isc_app_onrun() will have been posted (in
191258945Sroberto *	FIFO order) before isc_app_run() blocks.
192280849Scy *\li	'ctx' is a valid application context (for app_ctxrun()).
193258945Sroberto *
194258945Sroberto * Returns:
195258945Sroberto *\li	ISC_R_SUCCESS			Shutdown has been requested.
196258945Sroberto *\li	ISC_R_RELOAD			Reload has been requested.
197258945Sroberto */
198258945Sroberto
199258945Srobertoisc_result_t
200280849Scyisc_app_ctxshutdown(isc_appctx_t *ctx);
201280849Scy
202280849Scyisc_result_t
203258945Srobertoisc_app_shutdown(void);
204258945Sroberto/*!<
205258945Sroberto * \brief Request application shutdown.
206258945Sroberto *
207258945Sroberto * Notes:
208258945Sroberto *\li	It is safe to call isc_app_shutdown() multiple times.  Shutdown will
209258945Sroberto *	only be triggered once.
210258945Sroberto *
211258945Sroberto * Requires:
212280849Scy *\li	isc_app_[ctx]run() has been called.
213280849Scy *\li	'ctx' is a valid application context (for app_ctxshutdown()).
214258945Sroberto *
215258945Sroberto * Returns:
216258945Sroberto *\li	ISC_R_SUCCESS
217258945Sroberto *\li	ISC_R_UNEXPECTED
218258945Sroberto */
219258945Sroberto
220258945Srobertoisc_result_t
221280849Scyisc_app_ctxsuspend(isc_appctx_t *ctx);
222280849Scy/*!<
223280849Scy * \brief This has the same behavior as isc_app_ctxsuspend().
224280849Scy */
225280849Scy
226280849Scyisc_result_t
227258945Srobertoisc_app_reload(void);
228258945Sroberto/*!<
229258945Sroberto * \brief Request application reload.
230258945Sroberto *
231258945Sroberto * Requires:
232258945Sroberto *\li	isc_app_run() has been called.
233258945Sroberto *
234258945Sroberto * Returns:
235258945Sroberto *\li	ISC_R_SUCCESS
236258945Sroberto *\li	ISC_R_UNEXPECTED
237258945Sroberto */
238258945Sroberto
239258945Srobertovoid
240280849Scyisc_app_ctxfinish(isc_appctx_t *ctx);
241280849Scy
242280849Scyvoid
243258945Srobertoisc_app_finish(void);
244258945Sroberto/*!<
245258945Sroberto * \brief Finish an ISC library application.
246258945Sroberto *
247258945Sroberto * Notes:
248258945Sroberto *\li	This call should be made at or near the end of main().
249258945Sroberto *
250258945Sroberto * Requires:
251258945Sroberto *\li	isc_app_start() has been called.
252280849Scy *\li	'ctx' is a valid application context (for app_ctxfinish()).
253258945Sroberto *
254258945Sroberto * Ensures:
255258945Sroberto *\li	Any resources allocated by isc_app_start() have been released.
256258945Sroberto */
257258945Sroberto
258258945Srobertovoid
259258945Srobertoisc_app_block(void);
260258945Sroberto/*!<
261258945Sroberto * \brief Indicate that a blocking operation will be performed.
262258945Sroberto *
263258945Sroberto * Notes:
264258945Sroberto *\li	If a blocking operation is in process, a call to isc_app_shutdown()
265258945Sroberto *	or an external signal will abort the program, rather than allowing
266258945Sroberto *	clean shutdown.  This is primarily useful for reading user input.
267258945Sroberto *
268258945Sroberto * Requires:
269258945Sroberto * \li	isc_app_start() has been called.
270258945Sroberto * \li	No other blocking operations are in progress.
271258945Sroberto */
272258945Sroberto
273258945Srobertovoid
274258945Srobertoisc_app_unblock(void);
275258945Sroberto/*!<
276258945Sroberto * \brief Indicate that a blocking operation is complete.
277258945Sroberto *
278258945Sroberto * Notes:
279258945Sroberto * \li	When a blocking operation has completed, return the program to a
280258945Sroberto * 	state where a call to isc_app_shutdown() or an external signal will
281258945Sroberto * 	shutdown normally.
282258945Sroberto *
283258945Sroberto * Requires:
284258945Sroberto * \li	isc_app_start() has been called.
285258945Sroberto * \li	isc_app_block() has been called by the same thread.
286258945Sroberto */
287258945Sroberto
288280849Scyisc_result_t
289280849Scyisc_appctx_create(isc_mem_t *mctx, isc_appctx_t **ctxp);
290280849Scy/*!<
291280849Scy * \brief Create an application context.
292280849Scy *
293280849Scy * Requires:
294280849Scy *\li	'mctx' is a valid memory context.
295280849Scy *\li	'ctxp' != NULL && *ctxp == NULL.
296280849Scy */
297258945Sroberto
298280849Scyvoid
299280849Scyisc_appctx_destroy(isc_appctx_t **ctxp);
300280849Scy/*!<
301280849Scy * \brief Destroy an application context.
302280849Scy *
303280849Scy * Requires:
304280849Scy *\li	'*ctxp' is a valid application context.
305280849Scy *
306280849Scy * Ensures:
307280849Scy *\li	*ctxp == NULL.
308280849Scy */
309280849Scy
310280849Scyvoid
311280849Scyisc_appctx_settaskmgr(isc_appctx_t *ctx, isc_taskmgr_t *taskmgr);
312280849Scy/*!<
313280849Scy * \brief Associate a task manager with an application context.
314280849Scy *
315280849Scy * This must be done before running tasks within the application context.
316280849Scy *
317280849Scy * Requires:
318280849Scy *\li	'ctx' is a valid application context.
319280849Scy *\li	'taskmgr' is a valid task manager.
320280849Scy */
321280849Scy
322280849Scyvoid
323280849Scyisc_appctx_setsocketmgr(isc_appctx_t *ctx, isc_socketmgr_t *socketmgr);
324280849Scy/*!<
325280849Scy * \brief Associate a socket manager with an application context.
326280849Scy *
327280849Scy * This must be done before handling socket events within the application
328280849Scy * context.
329280849Scy *
330280849Scy * Requires:
331280849Scy *\li	'ctx' is a valid application context.
332280849Scy *\li	'socketmgr' is a valid socket manager.
333280849Scy */
334280849Scy
335280849Scyvoid
336280849Scyisc_appctx_settimermgr(isc_appctx_t *ctx, isc_timermgr_t *timermgr);
337280849Scy/*!<
338280849Scy * \brief Associate a socket timer with an application context.
339280849Scy *
340280849Scy * This must be done before handling timer events within the application
341280849Scy * context.
342280849Scy *
343280849Scy * Requires:
344280849Scy *\li	'ctx' is a valid application context.
345280849Scy *\li	'timermgr' is a valid timer manager.
346280849Scy */
347280849Scy
348280849Scy#ifdef USE_APPIMPREGISTER
349280849Scy/*%<
350280849Scy * See isc_appctx_create() above.
351280849Scy */
352280849Scytypedef isc_result_t
353280849Scy(*isc_appctxcreatefunc_t)(isc_mem_t *mctx, isc_appctx_t **ctxp);
354280849Scy
355280849Scyisc_result_t
356280849Scyisc_app_register(isc_appctxcreatefunc_t createfunc);
357280849Scy/*%<
358280849Scy * Register a new application implementation and add it to the list of
359280849Scy * supported implementations.  This function must be called when a different
360280849Scy * event library is used than the one contained in the ISC library.
361280849Scy */
362280849Scy
363280849Scyisc_result_t
364280849Scyisc__app_register(void);
365280849Scy/*%<
366280849Scy * A short cut function that specifies the application module in the ISC
367280849Scy * library for isc_app_register().  An application that uses the ISC library
368280849Scy * usually do not have to care about this function: it would call
369280849Scy * isc_lib_register(), which internally calls this function.
370280849Scy */
371280849Scy#endif /* USE_APPIMPREGISTER */
372280849Scy
373258945SrobertoISC_LANG_ENDDECLS
374258945Sroberto
375258945Sroberto#endif /* ISC_APP_H */
376