*/
int ast_register_atexit(void (*func)(void));
+/*!
+ * \since 11.9
+ * \brief Register a function to be executed before Asterisk gracefully exits.
+ *
+ * If Asterisk is immediately shutdown (core stop now, or sending the TERM
+ * signal), the callback is not run. When the callbacks are run, they are run in
+ * sequence with ast_register_atexit() callbacks, in the reverse order of
+ * registration.
+ *
+ * \param func The callback function to use.
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+int ast_register_cleanup(void (*func)(void));
+
/*!
* \brief Unregister a function registered with ast_register_atexit().
* \param func The callback function to unregister.
struct ast_atexit {
void (*func)(void);
+ int is_cleanup;
AST_LIST_ENTRY(ast_atexit) list;
};
#endif /* ! LOW_MEMORY */
-static void ast_run_atexits(void)
+static void ast_run_atexits(int run_cleanups)
{
struct ast_atexit *ae;
AST_LIST_LOCK(&atexits);
while ((ae = AST_LIST_REMOVE_HEAD(&atexits, list))) {
- if (ae->func) {
+ if (ae->func && (!ae->is_cleanup || run_cleanups)) {
ae->func();
}
ast_free(ae);
AST_LIST_TRAVERSE_SAFE_END;
}
-int ast_register_atexit(void (*func)(void))
+static int register_atexit(void (*func)(void), int is_cleanup)
{
struct ast_atexit *ae;
return -1;
}
ae->func = func;
+ ae->is_cleanup = is_cleanup;
AST_LIST_LOCK(&atexits);
__ast_unregister_atexit(func);
return 0;
}
+int ast_register_atexit(void (*func)(void))
+{
+ return register_atexit(func, 0);
+}
+
+int ast_register_cleanup(void (*func)(void))
+{
+ return register_atexit(func, 1);
+}
+
void ast_unregister_atexit(void (*func)(void))
{
AST_LIST_LOCK(&atexits);
static void really_quit(int num, shutdown_nice_t niceness, int restart)
{
int active_channels;
+ int run_cleanups = niceness >= SHUTDOWN_NICE;
- if (niceness >= SHUTDOWN_NICE) {
+ if (run_cleanups) {
ast_module_shutdown();
}
active_channels ? "uncleanly" : "cleanly", num);
ast_verb(0, "Executing last minute cleanups\n");
- ast_run_atexits();
+ ast_run_atexits(run_cleanups);
ast_debug(1, "Asterisk ending (%d).\n", num);
if (ast_socket > -1) {