app.h revision 290001
1/*
2 * Copyright (C) 2004-2007, 2009  Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1999-2001  Internet Software Consortium.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
16 */
17
18/* $Id: app.h,v 1.11 2009/09/02 23:48:03 tbox Exp $ */
19
20#ifndef ISC_APP_H
21#define ISC_APP_H 1
22
23/*****
24 ***** Module Info
25 *****/
26
27/*! \file isc/app.h
28 * \brief ISC Application Support
29 *
30 * Dealing with program termination can be difficult, especially in a
31 * multithreaded program.  The routines in this module help coordinate
32 * the shutdown process.  They are used as follows by the initial (main)
33 * thread of the application:
34 *
35 *\li		isc_app_start();	Call very early in main(), before
36 *					any other threads have been created.
37 *
38 *\li		isc_app_run();		This will post any on-run events,
39 *					and then block until application
40 *					shutdown is requested.  A shutdown
41 *					request is made by calling
42 *					isc_app_shutdown(), or by sending
43 *					SIGINT or SIGTERM to the process.
44 *					After isc_app_run() returns, the
45 *					application should shutdown itself.
46 *
47 *\li		isc_app_finish();	Call very late in main().
48 *
49 * Applications that want to use SIGHUP/isc_app_reload() to trigger reloading
50 * should check the result of isc_app_run() and call the reload routine if
51 * the result is ISC_R_RELOAD.  They should then call isc_app_run() again
52 * to resume waiting for reload or termination.
53 *
54 * Use of this module is not required.  In particular, isc_app_start() is
55 * NOT an ISC library initialization routine.
56 *
57 * This module also supports per-thread 'application contexts'.  With this
58 * mode, a thread-based application will have a separate context, in which
59 * it uses other ISC library services such as tasks or timers.  Signals are
60 * not caught in this mode, so that the application can handle the signals
61 * in its preferred way.
62 *
63 * \li MP:
64 *	Clients must ensure that isc_app_start(), isc_app_run(), and
65 *	isc_app_finish() are called at most once.  isc_app_shutdown()
66 *	is safe to use by any thread (provided isc_app_start() has been
67 *	called previously).
68 *
69 *	The same note applies to isc_app_ctxXXX() functions, but in this case
70 *	it's a per-thread restriction.  For example, a thread with an
71 *	application context must ensure that isc_app_ctxstart() with the
72 *	context is called at most once.
73 *
74 * \li Reliability:
75 *	No anticipated impact.
76 *
77 * \li Resources:
78 *	None.
79 *
80 * \li Security:
81 *	No anticipated impact.
82 *
83 * \li Standards:
84 *	None.
85 */
86
87#include <isc/eventclass.h>
88#include <isc/lang.h>
89#include <isc/magic.h>
90#include <isc/result.h>
91
92/***
93 *** Types
94 ***/
95
96typedef isc_event_t isc_appevent_t;
97
98#define ISC_APPEVENT_FIRSTEVENT		(ISC_EVENTCLASS_APP + 0)
99#define ISC_APPEVENT_SHUTDOWN		(ISC_EVENTCLASS_APP + 1)
100#define ISC_APPEVENT_LASTEVENT		(ISC_EVENTCLASS_APP + 65535)
101
102/*%
103 * app module methods.  Only app driver implementations use this structure.
104 * Other clients should use the top-level interfaces (i.e., isc_app_xxx
105 * functions).  magic must be ISCAPI_APPMETHODS_MAGIC.
106 */
107typedef struct isc_appmethods {
108	void		(*ctxdestroy)(isc_appctx_t **ctxp);
109	isc_result_t	(*ctxstart)(isc_appctx_t *ctx);
110	isc_result_t	(*ctxrun)(isc_appctx_t *ctx);
111	isc_result_t	(*ctxsuspend)(isc_appctx_t *ctx);
112	isc_result_t	(*ctxshutdown)(isc_appctx_t *ctx);
113	void		(*ctxfinish)(isc_appctx_t *ctx);
114	void		(*settaskmgr)(isc_appctx_t *ctx,
115				      isc_taskmgr_t *timermgr);
116	void		(*setsocketmgr)(isc_appctx_t *ctx,
117					isc_socketmgr_t *timermgr);
118	void		(*settimermgr)(isc_appctx_t *ctx,
119				       isc_timermgr_t *timermgr);
120} isc_appmethods_t;
121
122/*%
123 * This structure is actually just the common prefix of an application context
124 * implementation's version of an isc_appctx_t.
125 * \brief
126 * Direct use of this structure by clients is forbidden.  app implementations
127 * may change the structure.  'magic' must be ISCAPI_APPCTX_MAGIC for any
128 * of the isc_app_ routines to work.  app implementations must maintain
129 * all app context invariants.
130 */
131struct isc_appctx {
132	unsigned int		impmagic;
133	unsigned int		magic;
134	isc_appmethods_t	*methods;
135};
136
137#define ISCAPI_APPCTX_MAGIC		ISC_MAGIC('A','a','p','c')
138#define ISCAPI_APPCTX_VALID(c)		((c) != NULL && \
139					 (c)->magic == ISCAPI_APPCTX_MAGIC)
140
141ISC_LANG_BEGINDECLS
142
143isc_result_t
144isc_app_ctxstart(isc_appctx_t *ctx);
145
146isc_result_t
147isc_app_start(void);
148/*!<
149 * \brief Start an ISC library application.
150 *
151 * Notes:
152 *	This call should be made before any other ISC library call, and as
153 *	close to the beginning of the application as possible.
154 *
155 * Requires:
156 *	'ctx' is a valid application context (for app_ctxstart()).
157 */
158
159isc_result_t
160isc_app_onrun(isc_mem_t *mctx, isc_task_t *task, isc_taskaction_t action,
161	      void *arg);
162/*!<
163 * \brief Request delivery of an event when the application is run.
164 *
165 * Requires:
166 *\li	isc_app_start() has been called.
167 *
168 * Returns:
169 *	ISC_R_SUCCESS
170 *	ISC_R_NOMEMORY
171 */
172
173isc_result_t
174isc_app_ctxrun(isc_appctx_t *ctx);
175
176isc_result_t
177isc_app_run(void);
178/*!<
179 * \brief Run an ISC library application.
180 *
181 * Notes:
182 *\li	The caller (typically the initial thread of an application) will
183 *	block until shutdown is requested.  When the call returns, the
184 *	caller should start shutting down the application.
185 *
186 * Requires:
187 *\li	isc_app_[ctx]start() has been called.
188 *
189 * Ensures:
190 *\li	Any events requested via isc_app_onrun() will have been posted (in
191 *	FIFO order) before isc_app_run() blocks.
192 *\li	'ctx' is a valid application context (for app_ctxrun()).
193 *
194 * Returns:
195 *\li	ISC_R_SUCCESS			Shutdown has been requested.
196 *\li	ISC_R_RELOAD			Reload has been requested.
197 */
198
199isc_result_t
200isc_app_ctxshutdown(isc_appctx_t *ctx);
201
202isc_result_t
203isc_app_shutdown(void);
204/*!<
205 * \brief Request application shutdown.
206 *
207 * Notes:
208 *\li	It is safe to call isc_app_shutdown() multiple times.  Shutdown will
209 *	only be triggered once.
210 *
211 * Requires:
212 *\li	isc_app_[ctx]run() has been called.
213 *\li	'ctx' is a valid application context (for app_ctxshutdown()).
214 *
215 * Returns:
216 *\li	ISC_R_SUCCESS
217 *\li	ISC_R_UNEXPECTED
218 */
219
220isc_result_t
221isc_app_ctxsuspend(isc_appctx_t *ctx);
222/*!<
223 * \brief This has the same behavior as isc_app_ctxsuspend().
224 */
225
226isc_result_t
227isc_app_reload(void);
228/*!<
229 * \brief Request application reload.
230 *
231 * Requires:
232 *\li	isc_app_run() has been called.
233 *
234 * Returns:
235 *\li	ISC_R_SUCCESS
236 *\li	ISC_R_UNEXPECTED
237 */
238
239void
240isc_app_ctxfinish(isc_appctx_t *ctx);
241
242void
243isc_app_finish(void);
244/*!<
245 * \brief Finish an ISC library application.
246 *
247 * Notes:
248 *\li	This call should be made at or near the end of main().
249 *
250 * Requires:
251 *\li	isc_app_start() has been called.
252 *\li	'ctx' is a valid application context (for app_ctxfinish()).
253 *
254 * Ensures:
255 *\li	Any resources allocated by isc_app_start() have been released.
256 */
257
258void
259isc_app_block(void);
260/*!<
261 * \brief Indicate that a blocking operation will be performed.
262 *
263 * Notes:
264 *\li	If a blocking operation is in process, a call to isc_app_shutdown()
265 *	or an external signal will abort the program, rather than allowing
266 *	clean shutdown.  This is primarily useful for reading user input.
267 *
268 * Requires:
269 * \li	isc_app_start() has been called.
270 * \li	No other blocking operations are in progress.
271 */
272
273void
274isc_app_unblock(void);
275/*!<
276 * \brief Indicate that a blocking operation is complete.
277 *
278 * Notes:
279 * \li	When a blocking operation has completed, return the program to a
280 * 	state where a call to isc_app_shutdown() or an external signal will
281 * 	shutdown normally.
282 *
283 * Requires:
284 * \li	isc_app_start() has been called.
285 * \li	isc_app_block() has been called by the same thread.
286 */
287
288isc_result_t
289isc_appctx_create(isc_mem_t *mctx, isc_appctx_t **ctxp);
290/*!<
291 * \brief Create an application context.
292 *
293 * Requires:
294 *\li	'mctx' is a valid memory context.
295 *\li	'ctxp' != NULL && *ctxp == NULL.
296 */
297
298void
299isc_appctx_destroy(isc_appctx_t **ctxp);
300/*!<
301 * \brief Destroy an application context.
302 *
303 * Requires:
304 *\li	'*ctxp' is a valid application context.
305 *
306 * Ensures:
307 *\li	*ctxp == NULL.
308 */
309
310void
311isc_appctx_settaskmgr(isc_appctx_t *ctx, isc_taskmgr_t *taskmgr);
312/*!<
313 * \brief Associate a task manager with an application context.
314 *
315 * This must be done before running tasks within the application context.
316 *
317 * Requires:
318 *\li	'ctx' is a valid application context.
319 *\li	'taskmgr' is a valid task manager.
320 */
321
322void
323isc_appctx_setsocketmgr(isc_appctx_t *ctx, isc_socketmgr_t *socketmgr);
324/*!<
325 * \brief Associate a socket manager with an application context.
326 *
327 * This must be done before handling socket events within the application
328 * context.
329 *
330 * Requires:
331 *\li	'ctx' is a valid application context.
332 *\li	'socketmgr' is a valid socket manager.
333 */
334
335void
336isc_appctx_settimermgr(isc_appctx_t *ctx, isc_timermgr_t *timermgr);
337/*!<
338 * \brief Associate a socket timer with an application context.
339 *
340 * This must be done before handling timer events within the application
341 * context.
342 *
343 * Requires:
344 *\li	'ctx' is a valid application context.
345 *\li	'timermgr' is a valid timer manager.
346 */
347
348#ifdef USE_APPIMPREGISTER
349/*%<
350 * See isc_appctx_create() above.
351 */
352typedef isc_result_t
353(*isc_appctxcreatefunc_t)(isc_mem_t *mctx, isc_appctx_t **ctxp);
354
355isc_result_t
356isc_app_register(isc_appctxcreatefunc_t createfunc);
357/*%<
358 * Register a new application implementation and add it to the list of
359 * supported implementations.  This function must be called when a different
360 * event library is used than the one contained in the ISC library.
361 */
362
363isc_result_t
364isc__app_register(void);
365/*%<
366 * A short cut function that specifies the application module in the ISC
367 * library for isc_app_register().  An application that uses the ISC library
368 * usually do not have to care about this function: it would call
369 * isc_lib_register(), which internally calls this function.
370 */
371#endif /* USE_APPIMPREGISTER */
372
373ISC_LANG_ENDDECLS
374
375#endif /* ISC_APP_H */
376