AST_CLI_DEFINE(handle_cc_kill, "Kill a CC transaction"),
};
+static void cc_shutdown(void)
+{
+ ast_devstate_prov_del("ccss");
+ ast_cc_agent_unregister(&generic_agent_callbacks);
+ ast_cc_monitor_unregister(&generic_monitor_cbs);
+ ast_unregister_application(cccancel_app);
+ ast_unregister_application(ccreq_app);
+
+ if (cc_sched_thread) {
+ cc_sched_thread = ast_sched_thread_destroy(cc_sched_thread);
+ }
+ if (cc_core_taskprocessor) {
+ cc_core_taskprocessor = ast_taskprocessor_unreference(cc_core_taskprocessor);
+ }
+ if (generic_monitors) {
+ ao2_t_ref(generic_monitors, -1, "Unref generic_monitor container in cc_shutdown");
+ generic_monitors = NULL;
+ }
+ if (cc_core_instances) {
+ ao2_t_ref(cc_core_instances, -1, "Unref cc_core_instances container in cc_shutdown");
+ cc_core_instances = NULL;
+ }
+}
+
int ast_cc_init(void)
{
int res;
cc_logger_level = ast_logger_register_level(CC_LOGGER_LEVEL_NAME);
dialed_cc_interface_counter = 1;
initialize_cc_max_requests();
+ ast_register_atexit(cc_shutdown);
return res;
}
ao2_ref(appset, -1);
appset = NULL;
}
+ if (linkedids) {
+ ao2_ref(linkedids, -1);
+ linkedids = NULL;
+ }
}
int ast_cel_engine_init(void)
AST_DATA_ENTRY("/asterisk/core/channeltypes", &channeltypes_provider),
};
+static void channels_shutdown(void)
+{
+ ast_data_unregister(NULL);
+ if (channels) {
+ ao2_ref(channels, -1);
+ channels = NULL;
+ }
+}
+
void ast_channels_init(void)
{
channels = ao2_container_alloc(NUM_CHANNEL_BUCKETS,
ast_data_register_multiple_core(channel_providers, ARRAY_LEN(channel_providers));
ast_plc_reload();
+
+ ast_register_atexit(channels_shutdown);
}
/*! \brief Print call group and pickup group ---*/
#endif
+/*! \internal \brief Clean up resources on Asterisk shutdown */
+static void data_shutdown(void)
+{
+ ast_manager_unregister("DataGet");
+ ao2_t_ref(root_data.container, -1, "Unref root_data.container in data_shutdown");
+ ast_rwlock_destroy(&root_data.lock);
+}
+
int ast_data_init(void)
{
int res = 0;
AST_TEST_REGISTER(test_data_get);
#endif
+ ast_register_atexit(data_shutdown);
+
return res;
}
AST_CLI_DEFINE(event_dump_cache, "Dump the internal event cache (for debugging)"),
};
+/*! \internal \brief Clean up resources on Asterisk shutdown */
+static void event_shutdown(void)
+{
+ struct ast_event_sub *sub;
+ int i;
+
+ if (event_dispatcher) {
+ event_dispatcher = ast_taskprocessor_unreference(event_dispatcher);
+ }
+
+ /* Remove any remaining subscriptions. Note that we can't just call
+ * unsubscribe, as it will attempt to lock the subscription list
+ * as well */
+ for (i = 0; i < AST_EVENT_TOTAL; i++) {
+ AST_RWDLLIST_WRLOCK(&ast_event_subs[i]);
+ while ((sub = AST_RWDLLIST_REMOVE_HEAD(&ast_event_subs[i], entry))) {
+ ast_event_sub_destroy(sub);
+ }
+ AST_RWDLLIST_UNLOCK(&ast_event_subs[i]);
+ AST_RWDLLIST_HEAD_DESTROY(&ast_event_subs[i]);
+ }
+
+ for (i = 0; i < AST_EVENT_TOTAL; i++) {
+ if (!ast_event_cache[i].hash_fn) {
+ continue;
+ }
+ if (ast_event_cache[i].container) {
+ ao2_ref(ast_event_cache[i].container, -1);
+ }
+ }
+}
+
int ast_event_init(void)
{
int i;
if (!(ast_event_cache[i].container = ao2_container_alloc(NUM_CACHE_BUCKETS,
ast_event_hash, ast_event_cmp))) {
- return -1;
+ goto event_init_cleanup;
}
}
if (!(event_dispatcher = ast_taskprocessor_get("core_event_dispatcher", 0))) {
- return -1;
+ goto event_init_cleanup;
}
ast_cli_register_multiple(event_cli, ARRAY_LEN(event_cli));
+ ast_register_atexit(event_shutdown);
+
return 0;
+
+event_init_cleanup:
+ event_shutdown();
+ return -1;
}
size_t ast_event_minimum_length(void)
return -1;
}
ast_debug(1, "Configuration of default default parking lot done.\n");
- parkinglot_addref(default_parkinglot);
}
cfg = ast_config_load2("features.conf", "features", config_flags);
}
#endif /* defined(TEST_FRAMEWORK) */
+/*! \internal \brief Clean up resources on Asterisk shutdown */
+static void features_shutdown(void)
+{
+ ast_devstate_prov_del("Park");
+ ast_manager_unregister("Bridge");
+ ast_manager_unregister("Park");
+ ast_manager_unregister("Parkinglots");
+ ast_manager_unregister("ParkedCalls");
+ ast_unregister_application(parkcall);
+ ast_unregister_application(parkedcall);
+ ast_unregister_application(app_bridge);
+
+ pthread_cancel(parking_thread);
+ ao2_ref(parkinglots, -1);
+}
+
int ast_features_init(void)
{
int res;
res |= AST_TEST_REGISTER(features_test);
#endif /* defined(TEST_FRAMEWORK) */
+ ast_register_atexit(features_shutdown);
+
return res;
}
return 0;
}
+/*! \internal \brief Clean up resources on Asterisk shutdown */
+static void indications_shutdown(void)
+{
+ if (ast_tone_zones) {
+ ao2_ref(ast_tone_zones, -1);
+ ast_tone_zones = NULL;
+ }
+}
+
/*! \brief Load indications module */
int ast_indications_init(void)
{
ast_cli_register_multiple(cli_indications, ARRAY_LEN(cli_indications));
+ ast_register_atexit(indications_shutdown);
return 0;
}
AST_RWLIST_UNLOCK(&channelvars);
}
+/*! \internal \brief Clean up resources on Asterisk shutdown */
+static void manager_shutdown(void)
+{
+ struct ast_manager_user *user;
+
+ if (registered) {
+ ast_manager_unregister("Ping");
+ ast_manager_unregister("Events");
+ ast_manager_unregister("Logoff");
+ ast_manager_unregister("Login");
+ ast_manager_unregister("Challenge");
+ ast_manager_unregister("Hangup");
+ ast_manager_unregister("Status");
+ ast_manager_unregister("Setvar");
+ ast_manager_unregister("Getvar");
+ ast_manager_unregister("GetConfig");
+ ast_manager_unregister("GetConfigJSON");
+ ast_manager_unregister("UpdateConfig");
+ ast_manager_unregister("CreateConfig");
+ ast_manager_unregister("ListCategories");
+ ast_manager_unregister("Redirect");
+ ast_manager_unregister("Atxfer");
+ ast_manager_unregister("Originate");
+ ast_manager_unregister("Command");
+ ast_manager_unregister("ExtensionState");
+ ast_manager_unregister("AbsoluteTimeout");
+ ast_manager_unregister("MailboxStatus");
+ ast_manager_unregister("MailboxCount");
+ ast_manager_unregister("ListCommands");
+ ast_manager_unregister("SendText");
+ ast_manager_unregister("UserEvent");
+ ast_manager_unregister("WaitEvent");
+ ast_manager_unregister("CoreSettings");
+ ast_manager_unregister("CoreStatus");
+ ast_manager_unregister("Reload");
+ ast_manager_unregister("CoreShowChannels");
+ ast_manager_unregister("ModuleLoad");
+ ast_manager_unregister("ModuleCheck");
+ ast_manager_unregister("AOCMessage");
+ ast_manager_unregister("Filter");
+ }
+
+ if (sessions) {
+ ao2_ref(sessions, -1);
+ sessions = NULL;
+ }
+
+ while ((user = AST_LIST_REMOVE_HEAD(&users, list))) {
+ ao2_ref(user->whitefilters, -1);
+ ao2_ref(user->blackfilters, -1);
+ ast_free(user);
+ }
+}
+
+
static int __init_manager(int reload)
{
struct ast_config *ucfg = NULL, *cfg = NULL;
/* Append placeholder event so master_eventq never runs dry */
append_event("Event: Placeholder\r\n\r\n", 0);
}
+
+ ast_register_atexit(manager_shutdown);
+
if ((cfg = ast_config_load2("manager.conf", "manager", config_flags)) == CONFIG_STATUS_FILEUNCHANGED) {
return 0;
}
} else if (ast_ssl_setup(amis_desc.tls_cfg)) {
ast_tcptls_server_start(&amis_desc);
}
+
return 0;
}
AST_DATA_ENTRY("asterisk/core/hints", &hints_data_provider),
};
+/*! \internal \brief Clean up resources on Asterisk shutdown.
+ * \note Cleans up resources allocated in load_pbx */
+static void unload_pbx(void)
+{
+ int x;
+
+ if (device_state_sub) {
+ device_state_sub = ast_event_unsubscribe(device_state_sub);
+ }
+
+ /* Unregister builtin applications */
+ for (x = 0; x < ARRAY_LEN(builtins); x++) {
+ ast_unregister_application(builtins[x].name);
+ }
+ ast_manager_unregister("ShowDialPlan");
+ ast_custom_function_unregister(&exception_function);
+ ast_custom_function_unregister(&testtime_function);
+ ast_data_unregister(NULL);
+}
+
int load_pbx(void)
{
int x;
return -1;
}
+ ast_register_atexit(unload_pbx);
return 0;
}
AST_CLI_DEFINE(cli_tps_report, "List instantiated task processors and statistics"),
};
+/*! \internal \brief Clean up resources on Asterisk shutdown */
+static void tps_shutdown(void)
+{
+ ao2_t_ref(tps_singletons, -1, "Unref tps_singletons in shutdown");
+}
+
/* initialize the taskprocessor container and register CLI operations */
int ast_tps_init(void)
{
ast_cond_init(&cli_ping_cond, NULL);
ast_cli_register_multiple(taskprocessor_clis, ARRAY_LEN(taskprocessor_clis));
+
+ ast_register_atexit(tps_shutdown);
+
return 0;
}
static void ast_moh_destroy(void)
{
ast_verb(2, "Destroying musiconhold processes\n");
- ao2_t_callback(mohclasses, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL, "Destroy callback");
+ if (mohclasses) {
+ ao2_t_callback(mohclasses, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL, "Destroy callback");
+ ao2_ref(mohclasses, -1);
+ mohclasses = NULL;
+ }
}
static char *handle_cli_moh_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)