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