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