From 81db0aca0fb8d288a780ca664817ef231a9a4ac0 Mon Sep 17 00:00:00 2001 From: George Joseph Date: Mon, 29 Jan 2018 12:46:36 -0700 Subject: [PATCH] res_pjsip_registrar_expire: Refactor into res_pjsip_register res_pjsip_registrar_expire remains as an empty module for now. Change-Id: Ib93698938bae548d2199cb542f3692d1a171239f --- res/res_pjsip_registrar.c | 100 ++++++++++++++++++++++++++ res/res_pjsip_registrar_expire.c | 117 ++----------------------------- 2 files changed, 107 insertions(+), 110 deletions(-) diff --git a/res/res_pjsip_registrar.c b/res/res_pjsip_registrar.c index 00981fb775..078e13ee28 100644 --- a/res/res_pjsip_registrar.c +++ b/res/res_pjsip_registrar.c @@ -1091,6 +1091,93 @@ static pjsip_module registrar_module = { .on_rx_request = registrar_on_rx_request, }; +/*! \brief Thread keeping things alive */ +static pthread_t check_thread = AST_PTHREADT_NULL; + +/*! \brief The global interval at which to check for contact expiration */ +static unsigned int check_interval; + +/*! \brief Callback function which deletes a contact */ +static int expire_contact(void *obj, void *arg, int flags) +{ + struct ast_sip_contact *contact = obj; + struct ast_named_lock *lock; + + lock = ast_named_lock_get(AST_NAMED_LOCK_TYPE_MUTEX, "aor", contact->aor); + if (!lock) { + return 0; + } + + /* + * We need to check the expiration again with the aor lock held + * in case another thread is attempting to renew the contact. + */ + ao2_lock(lock); + if (ast_tvdiff_ms(ast_tvnow(), contact->expiration_time) > 0) { + ast_sip_location_delete_contact(contact); + } + ao2_unlock(lock); + ast_named_lock_put(lock); + + return 0; +} + +static void *check_expiration_thread(void *data) +{ + struct ao2_container *contacts; + struct ast_variable *var; + char *time = alloca(64); + + while (check_interval) { + sleep(check_interval); + + sprintf(time, "%ld", ast_tvnow().tv_sec); + var = ast_variable_new("expiration_time <=", time, ""); + + ast_debug(4, "Woke up at %s Interval: %d\n", time, check_interval); + + contacts = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "contact", + AST_RETRIEVE_FLAG_MULTIPLE, var); + + ast_variables_destroy(var); + if (contacts) { + ast_debug(3, "Expiring %d contacts\n", ao2_container_count(contacts)); + ao2_callback(contacts, OBJ_NODATA, expire_contact, NULL); + ao2_ref(contacts, -1); + } + } + + return NULL; +} + +static void expiration_global_loaded(const char *object_type) +{ + check_interval = ast_sip_get_contact_expiration_check_interval(); + + /* Observer calls are serialized so this is safe without it's own lock */ + if (check_interval) { + if (check_thread == AST_PTHREADT_NULL) { + if (ast_pthread_create_background(&check_thread, NULL, check_expiration_thread, NULL)) { + ast_log(LOG_ERROR, "Could not create thread for checking contact expiration.\n"); + return; + } + ast_debug(3, "Interval = %d, starting thread\n", check_interval); + } + } else { + if (check_thread != AST_PTHREADT_NULL) { + pthread_kill(check_thread, SIGURG); + pthread_join(check_thread, NULL); + check_thread = AST_PTHREADT_NULL; + ast_debug(3, "Interval = 0, shutting thread down\n"); + } + } +} + +/*! \brief Observer which is used to update our interval when the global setting changes */ +static struct ast_sorcery_observer expiration_global_observer = { + .loaded = expiration_global_loaded, +}; + static int load_module(void) { const pj_str_t STR_REGISTER = { "REGISTER", 8 }; @@ -1113,11 +1200,24 @@ static int load_module(void) ast_manager_register_xml(AMI_SHOW_REGISTRATION_CONTACT_STATUSES, EVENT_FLAG_SYSTEM, ami_show_registration_contact_statuses); + ast_sorcery_observer_add(ast_sip_get_sorcery(), "global", &expiration_global_observer); + ast_sorcery_reload_object(ast_sip_get_sorcery(), "global"); + return AST_MODULE_LOAD_SUCCESS; } static int unload_module(void) { + if (check_thread != AST_PTHREADT_NULL) { + check_interval = 0; + pthread_kill(check_thread, SIGURG); + pthread_join(check_thread, NULL); + + check_thread = AST_PTHREADT_NULL; + } + + ast_sorcery_observer_remove(ast_sip_get_sorcery(), "global", &expiration_global_observer); + ast_manager_unregister(AMI_SHOW_REGISTRATIONS); ast_manager_unregister(AMI_SHOW_REGISTRATION_CONTACT_STATUSES); ast_sip_unregister_service(®istrar_module); diff --git a/res/res_pjsip_registrar_expire.c b/res/res_pjsip_registrar_expire.c index e89ea03326..4c2189552e 100644 --- a/res/res_pjsip_registrar_expire.c +++ b/res/res_pjsip_registrar_expire.c @@ -19,132 +19,29 @@ /*** MODULEINFO pjproject res_pjsip - core + extended ***/ +/* + * This module has been refactored into res_pjsip_registrar + */ + #include "asterisk.h" -#include -#include -#include - -#include "asterisk/res_pjsip.h" #include "asterisk/module.h" -#include "asterisk/named_locks.h" - -/*! \brief Thread keeping things alive */ -static pthread_t check_thread = AST_PTHREADT_NULL; - -/*! \brief The global interval at which to check for contact expiration */ -static unsigned int check_interval; - -/*! \brief Callback function which deletes a contact */ -static int expire_contact(void *obj, void *arg, int flags) -{ - struct ast_sip_contact *contact = obj; - struct ast_named_lock *lock; - - lock = ast_named_lock_get(AST_NAMED_LOCK_TYPE_MUTEX, "aor", contact->aor); - if (!lock) { - return 0; - } - - /* - * We need to check the expiration again with the aor lock held - * in case another thread is attempting to renew the contact. - */ - ao2_lock(lock); - if (ast_tvdiff_ms(ast_tvnow(), contact->expiration_time) > 0) { - ast_sip_location_delete_contact(contact); - } - ao2_unlock(lock); - ast_named_lock_put(lock); - - return 0; -} - -static void *check_expiration_thread(void *data) -{ - struct ao2_container *contacts; - struct ast_variable *var; - char *time = alloca(64); - - while (check_interval) { - sleep(check_interval); - - sprintf(time, "%ld", ast_tvnow().tv_sec); - var = ast_variable_new("expiration_time <=", time, ""); - - ast_debug(4, "Woke up at %s Interval: %d\n", time, check_interval); - - contacts = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "contact", - AST_RETRIEVE_FLAG_MULTIPLE, var); - - ast_variables_destroy(var); - if (contacts) { - ast_debug(3, "Expiring %d contacts\n", ao2_container_count(contacts)); - ao2_callback(contacts, OBJ_NODATA, expire_contact, NULL); - ao2_ref(contacts, -1); - } - } - - return NULL; -} - -static void expiration_global_loaded(const char *object_type) -{ - check_interval = ast_sip_get_contact_expiration_check_interval(); - - /* Observer calls are serialized so this is safe without it's own lock */ - if (check_interval) { - if (check_thread == AST_PTHREADT_NULL) { - if (ast_pthread_create_background(&check_thread, NULL, check_expiration_thread, NULL)) { - ast_log(LOG_ERROR, "Could not create thread for checking contact expiration.\n"); - return; - } - ast_debug(3, "Interval = %d, starting thread\n", check_interval); - } - } else { - if (check_thread != AST_PTHREADT_NULL) { - pthread_kill(check_thread, SIGURG); - pthread_join(check_thread, NULL); - check_thread = AST_PTHREADT_NULL; - ast_debug(3, "Interval = 0, shutting thread down\n"); - } - } -} - -/*! \brief Observer which is used to update our interval when the global setting changes */ -static struct ast_sorcery_observer expiration_global_observer = { - .loaded = expiration_global_loaded, -}; static int unload_module(void) { - if (check_thread != AST_PTHREADT_NULL) { - check_interval = 0; - pthread_kill(check_thread, SIGURG); - pthread_join(check_thread, NULL); - - check_thread = AST_PTHREADT_NULL; - } - - ast_sorcery_observer_remove(ast_sip_get_sorcery(), "global", &expiration_global_observer); - return 0; } - static int load_module(void) { - ast_sorcery_observer_add(ast_sip_get_sorcery(), "global", &expiration_global_observer); - ast_sorcery_reload_object(ast_sip_get_sorcery(), "global"); - return AST_MODULE_LOAD_SUCCESS; } -AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP Contact Auto-Expiration", - .support_level = AST_MODULE_SUPPORT_CORE, +AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "OBSOLETE PJSIP Contact Auto-Expiration", + .support_level = AST_MODULE_SUPPORT_EXTENDED, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_APP_DEPEND,