xref: /freebsd/contrib/ntp/libntp/lib/isc/include/isc/app.h (revision a466cc55373fc3cf86837f09da729535b57e69a1)
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 
96 typedef 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  */
107 typedef 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  */
131 struct 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 
141 ISC_LANG_BEGINDECLS
142 
143 isc_result_t
144 isc_app_ctxstart(isc_appctx_t *ctx);
145 
146 isc_result_t
147 isc_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 
159 isc_result_t
160 isc_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 
173 isc_result_t
174 isc_app_ctxrun(isc_appctx_t *ctx);
175 
176 isc_result_t
177 isc_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 
199 isc_result_t
200 isc_app_ctxshutdown(isc_appctx_t *ctx);
201 
202 isc_result_t
203 isc_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 
220 isc_result_t
221 isc_app_ctxsuspend(isc_appctx_t *ctx);
222 /*!<
223  * \brief This has the same behavior as isc_app_ctxsuspend().
224  */
225 
226 isc_result_t
227 isc_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 
239 void
240 isc_app_ctxfinish(isc_appctx_t *ctx);
241 
242 void
243 isc_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 
258 void
259 isc_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 
273 void
274 isc_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 
288 isc_result_t
289 isc_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 
298 void
299 isc_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 
310 void
311 isc_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 
322 void
323 isc_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 
335 void
336 isc_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  */
352 typedef isc_result_t
353 (*isc_appctxcreatefunc_t)(isc_mem_t *mctx, isc_appctx_t **ctxp);
354 
355 isc_result_t
356 isc_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 
363 isc_result_t
364 isc__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 
373 ISC_LANG_ENDDECLS
374 
375 #endif /* ISC_APP_H */
376