diff --git a/include/asterisk/sorcery.h b/include/asterisk/sorcery.h index 84a537937d4d916d4e6b08a4a4b3d087190e0ab3..dad0c439c1caebc42ab4f22441e0c3b77fe6b5ee 100644 --- a/include/asterisk/sorcery.h +++ b/include/asterisk/sorcery.h @@ -356,7 +356,7 @@ int __ast_sorcery_apply_default(struct ast_sorcery *sorcery, const char *type, c * \retval 0 success * \retval -1 failure */ -int __ast_sorcery_object_register(struct ast_sorcery *sorcery, const char *type, unsigned int hidden, aco_type_item_alloc alloc, sorcery_transform_handler transform, sorcery_apply_handler apply); +int __ast_sorcery_object_register(struct ast_sorcery *sorcery, const char *type, unsigned int hidden, unsigned int reloadable, aco_type_item_alloc alloc, sorcery_transform_handler transform, sorcery_apply_handler apply); /*! * \brief Register an object type @@ -371,7 +371,22 @@ int __ast_sorcery_object_register(struct ast_sorcery *sorcery, const char *type, * \retval -1 failure */ #define ast_sorcery_object_register(sorcery, type, alloc, transform, apply) \ - __ast_sorcery_object_register((sorcery), (type), 0, (alloc), (transform), (apply)) + __ast_sorcery_object_register((sorcery), (type), 0, 1, (alloc), (transform), (apply)) + +/*! + * \brief Register an object type that is not reloadable + * + * \param sorcery Pointer to a sorcery structure + * \param type Type of object + * \param alloc Required object allocation callback + * \param transform Optional transformation callback + * \param apply Optional object set apply callback + * + * \retval 0 success + * \retval -1 failure + */ +#define ast_sorcery_object_register_no_reload(sorcery, type, alloc, transform, apply) \ + __ast_sorcery_object_register((sorcery), (type), 0, 0, (alloc), (transform), (apply)) /*! * \brief Register an internal, hidden object type @@ -386,7 +401,7 @@ int __ast_sorcery_object_register(struct ast_sorcery *sorcery, const char *type, * \retval -1 failure */ #define ast_sorcery_internal_object_register(sorcery, type, alloc, transform, apply) \ - __ast_sorcery_object_register((sorcery), (type), 1, (alloc), (transform), (apply)) + __ast_sorcery_object_register((sorcery), (type), 1, 1, (alloc), (transform), (apply)) /*! * \brief Set the copy handler for an object type diff --git a/main/sorcery.c b/main/sorcery.c index 1bd55d4533e457c6fd0ff79716aa290b6e870576..3f2346dfeeed1c2de0472b2fb0a138d8ce8df912 100644 --- a/main/sorcery.c +++ b/main/sorcery.c @@ -110,6 +110,9 @@ struct ast_sorcery_object_type { /*! \brief Serializer for observers */ struct ast_taskprocessor *serializer; + + /*! \brief Specifies if object type is reloadable or not */ + unsigned int reloadable:1; }; /*! \brief Structure for registered object type observer */ @@ -575,7 +578,7 @@ static int sorcery_extended_fields_handler(const void *obj, struct ast_variable return 0; } -int __ast_sorcery_object_register(struct ast_sorcery *sorcery, const char *type, unsigned int hidden, aco_type_item_alloc alloc, sorcery_transform_handler transform, sorcery_apply_handler apply) +int __ast_sorcery_object_register(struct ast_sorcery *sorcery, const char *type, unsigned int hidden, unsigned int reloadable, aco_type_item_alloc alloc, sorcery_transform_handler transform, sorcery_apply_handler apply) { RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, type, OBJ_KEY), ao2_cleanup); @@ -589,6 +592,7 @@ int __ast_sorcery_object_register(struct ast_sorcery *sorcery, const char *type, object_type->type.item_alloc = alloc; object_type->type.hidden = hidden; + object_type->reloadable = reloadable; object_type->transform = transform; object_type->apply = apply; object_type->file->types[0] = &object_type->type; @@ -695,12 +699,26 @@ int __ast_sorcery_object_field_register(struct ast_sorcery *sorcery, const char return 0; } +/*! \brief Retrieves whether or not the type is reloadable */ +static int sorcery_reloadable(const struct ast_sorcery *sorcery, const char *type) +{ + RAII_VAR(struct ast_sorcery_object_type *, object_type, + ao2_find(sorcery->types, type, OBJ_KEY), ao2_cleanup); + return object_type && object_type->reloadable; +} + static int sorcery_wizard_load(void *obj, void *arg, int flags) { struct ast_sorcery_object_wizard *wizard = obj; struct sorcery_load_details *details = arg; void (*load)(void *data, const struct ast_sorcery *sorcery, const char *type); + if (details->reload && !sorcery_reloadable(details->sorcery, details->type)) { + ast_log(LOG_NOTICE, "Type '%s' is not reloadable, " + "maintaining previous values\n", details->type); + return 0; + } + load = !details->reload ? wizard->wizard->load : wizard->wizard->reload; if (load) { diff --git a/res/res_pjsip.c b/res/res_pjsip.c index e7c83d9d160a96694ba164e095187970c3ff5c34..d9d841472491ee570d74b17fc6ec887a68b1f648 100644 --- a/res/res_pjsip.c +++ b/res/res_pjsip.c @@ -1290,6 +1290,8 @@ static int sip_get_tpselector_from_endpoint(const struct ast_sip_endpoint *endpo transport = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "transport", transport_name); if (!transport || !transport->state) { + ast_log(LOG_ERROR, "Unable to retrieve PJSIP transport '%s' for endpoint '%s'\n", + transport_name, ast_sorcery_object_get_id(endpoint)); return -1; } diff --git a/res/res_pjsip/config_transport.c b/res/res_pjsip/config_transport.c index 82a995cb6a51b1e546f74a07081521e06376bef0..cf0b5e878799aeeae0171c76298cfa318245a699 100644 --- a/res/res_pjsip/config_transport.c +++ b/res/res_pjsip/config_transport.c @@ -309,7 +309,7 @@ int ast_sip_initialize_sorcery_transport(struct ast_sorcery *sorcery) { ast_sorcery_apply_default(sorcery, "transport", "config", "pjsip.conf,criteria=type=transport"); - if (ast_sorcery_object_register(sorcery, "transport", transport_alloc, NULL, transport_apply)) { + if (ast_sorcery_object_register_no_reload(sorcery, "transport", transport_alloc, NULL, transport_apply)) { return -1; } diff --git a/res/res_pjsip_outbound_registration.c b/res/res_pjsip_outbound_registration.c index 67e0ead3370cf0f098d1d1bcba3871200ca6c6d5..166b557773f3a93dbcb71aa5e18987417f618d6f 100644 --- a/res/res_pjsip_outbound_registration.c +++ b/res/res_pjsip_outbound_registration.c @@ -602,6 +602,8 @@ static int sip_outbound_registration_regc_alloc(void *data) RAII_VAR(struct ast_sip_transport *, transport, ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "transport", registration->transport), ao2_cleanup); if (!transport || !transport->state) { + ast_log(LOG_ERROR, "Unable to retrieve PJSIP transport '%s' " + " for outbound registration", registration->transport); return -1; }