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