Index: include/asterisk.h =================================================================== --- include/asterisk.h (revision 150698) +++ include/asterisk.h (working copy) @@ -60,6 +60,21 @@ */ void ast_unregister_atexit(void (*func)(void)); +/*! + * \brief Register a function to be executed after Asterisk started. + * \param func The callback function to use. + * + * \retval 0 on success. + * \retval -1 on error. + */ +int ast_register_atstarted(void (*func)(void)); + +/*! + * \brief Unregister a function registered with ast_register_atstarted(). + * \param func The callback function to unregister. + */ +void ast_unregister_atstarted(void (*func)(void)); + #if !defined(LOW_MEMORY) /*! * \brief Register the version of a source code file with the core. Index: main/asterisk.c =================================================================== --- main/asterisk.c (revision 150698) +++ main/asterisk.c (working copy) @@ -184,6 +184,13 @@ static AST_RWLIST_HEAD_STATIC(atexits, ast_atexit); +struct ast_atstarted { + void (*func)(void); + AST_RWLIST_ENTRY(ast_atstarted) list; +}; + +static AST_RWLIST_HEAD_STATIC(atstarteds, ast_atstarted); + struct timeval ast_startuptime; struct timeval ast_lastreloadtime; @@ -804,6 +811,42 @@ free(ae); } +int ast_register_atstarted(void (*func)(void)) +{ + struct ast_atstarted *ae; + + if (!(ae = ast_calloc(1, sizeof(*ae)))) + return -1; + + ae->func = func; + + ast_unregister_atstarted(func); + + AST_RWLIST_WRLOCK(&atstarteds); + AST_RWLIST_INSERT_HEAD(&atstarteds, ae, list); + AST_RWLIST_UNLOCK(&atstarteds); + + return 0; +} + +void ast_unregister_atstarted(void (*func)(void)) +{ + struct ast_atstarted *ae = NULL; + + AST_RWLIST_WRLOCK(&atstarteds); + AST_RWLIST_TRAVERSE_SAFE_BEGIN(&atstarteds, ae, list) { + if (ae->func == func) { + AST_RWLIST_REMOVE_CURRENT(list); + break; + } + } + AST_RWLIST_TRAVERSE_SAFE_END; + AST_RWLIST_UNLOCK(&atstarteds); + + if (ae) + free(ae); +} + /* Sending commands from consoles back to the daemon requires a terminating NULL */ static int fdsend(int fd, const char *s) { @@ -1326,6 +1369,17 @@ AST_RWLIST_UNLOCK(&atexits); } +static void ast_run_atstarteds(void) +{ + struct ast_atstarted *ae; + AST_RWLIST_RDLOCK(&atstarteds); + AST_RWLIST_TRAVERSE(&atstarteds, ae, list) { + if (ae->func) + ae->func(); + } + AST_RWLIST_UNLOCK(&atstarteds); +} + static void quit_handler(int num, int niceness, int safeshutdown, int restart) { char filename[80] = ""; @@ -3334,6 +3388,9 @@ dnsmgr_start_refresh(); + /* run commands for post startup */ + ast_run_atstarteds(); + /* We might have the option of showing a console, but for now just do nothing... */ if (ast_opt_console && !option_verbose)