From 3357c494cb21f24b7185ee3b255bc0cd72d48a55 Mon Sep 17 00:00:00 2001 From: Richard Mudgett <rmudgett@digium.com> Date: Tue, 3 Dec 2013 17:35:54 +0000 Subject: [PATCH] sorcery, bucket: Change observer remove calls to take const callbacks struct. * Make ast_sorcery_observer_remove() accept a const callbacks struct. * Make ast_sorcery_observer_remove() tolerant of the sorcery parameter being NULL. Now it can be called within a module unload routine if the sorcery initialization fails. * Fix ast_sorcery_observer_add() to fail if the container link fails. ........ Merged revisions 403324 from http://svn.asterisk.org/svn/asterisk/branches/12 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@403327 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- include/asterisk/bucket.h | 4 ++-- include/asterisk/sorcery.h | 5 +++-- main/bucket.c | 4 ++-- main/sorcery.c | 20 +++++++++++++++----- res/res_pjsip/pjsip_configuration.c | 2 +- res/res_pjsip/pjsip_options.c | 2 +- res/res_pjsip_registrar_expire.c | 2 +- tests/test_sorcery.c | 2 +- 8 files changed, 26 insertions(+), 15 deletions(-) diff --git a/include/asterisk/bucket.h b/include/asterisk/bucket.h index a09ade5fd5..c07fb0cbd2 100644 --- a/include/asterisk/bucket.h +++ b/include/asterisk/bucket.h @@ -256,7 +256,7 @@ int ast_bucket_observer_add(const struct ast_sorcery_observer *callbacks); * * \param callbacks Implementation of the sorcery observer interface */ -void ast_bucket_observer_remove(struct ast_sorcery_observer *callbacks); +void ast_bucket_observer_remove(const struct ast_sorcery_observer *callbacks); /*! * \brief Get a JSON representation of a bucket @@ -359,7 +359,7 @@ int ast_bucket_file_observer_add(const struct ast_sorcery_observer *callbacks); * * \param callbacks Implementation of the sorcery observer interface */ -void ast_bucket_file_observer_remove(struct ast_sorcery_observer *callbacks); +void ast_bucket_file_observer_remove(const struct ast_sorcery_observer *callbacks); /*! * \brief Get a JSON representation of a bucket file diff --git a/include/asterisk/sorcery.h b/include/asterisk/sorcery.h index 8ce3eccf3f..1402c58339 100644 --- a/include/asterisk/sorcery.h +++ b/include/asterisk/sorcery.h @@ -349,6 +349,7 @@ int __ast_sorcery_apply_default(struct ast_sorcery *sorcery, const char *type, c * \param sorcery Pointer to a sorcery structure * \param type Type of object * \param hidden All objects of this type are internal and should not be manipulated by users + * \param reloadable All objects of this type are reloadable * \param alloc Required object allocation callback * \param transform Optional transformation callback * \param apply Optional object set apply callback @@ -689,7 +690,7 @@ int ast_sorcery_observer_add(const struct ast_sorcery *sorcery, const char *type * \retval 0 success * \retval -1 failure */ -void ast_sorcery_observer_remove(const struct ast_sorcery *sorcery, const char *type, struct ast_sorcery_observer *callbacks); +void ast_sorcery_observer_remove(const struct ast_sorcery *sorcery, const char *type, const struct ast_sorcery_observer *callbacks); /*! * \brief Create and potentially persist an object using an available wizard @@ -720,7 +721,7 @@ void *ast_sorcery_retrieve_by_id(const struct ast_sorcery *sorcery, const char * * \param sorcery Pointer to a sorcery structure * \param type Type of object to retrieve * \param flags Flags to control behavior - * \param fields Optional jbject fields and values to match against + * \param fields Optional object fields and values to match against * * \retval non-NULL if found * \retval NULL if not found diff --git a/main/bucket.c b/main/bucket.c index 10d230b7b1..b3a0d3ca94 100644 --- a/main/bucket.c +++ b/main/bucket.c @@ -473,7 +473,7 @@ int ast_bucket_observer_add(const struct ast_sorcery_observer *callbacks) return ast_sorcery_observer_add(bucket_sorcery, "bucket", callbacks); } -void ast_bucket_observer_remove(struct ast_sorcery_observer *callbacks) +void ast_bucket_observer_remove(const struct ast_sorcery_observer *callbacks) { ast_sorcery_observer_remove(bucket_sorcery, "bucket", callbacks); } @@ -763,7 +763,7 @@ int ast_bucket_file_observer_add(const struct ast_sorcery_observer *callbacks) return ast_sorcery_observer_add(bucket_sorcery, "file", callbacks); } -void ast_bucket_file_observer_remove(struct ast_sorcery_observer *callbacks) +void ast_bucket_file_observer_remove(const struct ast_sorcery_observer *callbacks) { ast_sorcery_observer_remove(bucket_sorcery, "file", callbacks); } diff --git a/main/sorcery.c b/main/sorcery.c index 99ee2a90eb..845ae61498 100644 --- a/main/sorcery.c +++ b/main/sorcery.c @@ -1526,6 +1526,7 @@ int ast_sorcery_observer_add(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); struct ast_sorcery_object_type_observer *observer; + int res; if (!object_type || !callbacks) { return -1; @@ -1536,10 +1537,13 @@ int ast_sorcery_observer_add(const struct ast_sorcery *sorcery, const char *type } observer->callbacks = callbacks; - ao2_link(object_type->observers, observer); + res = 0; + if (!ao2_link(object_type->observers, observer)) { + res = -1; + } ao2_ref(observer, -1); - return 0; + return res; } /*! \brief Internal callback function for removing an observer */ @@ -1550,13 +1554,19 @@ static int sorcery_observer_remove(void *obj, void *arg, int flags) return (observer->callbacks == arg) ? CMP_MATCH | CMP_STOP : 0; } -void ast_sorcery_observer_remove(const struct ast_sorcery *sorcery, const char *type, struct ast_sorcery_observer *callbacks) +void ast_sorcery_observer_remove(const struct ast_sorcery *sorcery, const char *type, const struct ast_sorcery_observer *callbacks) { - RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, type, OBJ_KEY), ao2_cleanup); + RAII_VAR(struct ast_sorcery_object_type *, object_type, NULL, ao2_cleanup); + struct ast_sorcery_observer *cbs = (struct ast_sorcery_observer *) callbacks;/* Remove const for traversal. */ + if (!sorcery) { + return; + } + object_type = ao2_find(sorcery->types, type, OBJ_KEY); if (!object_type) { return; } - ao2_callback(object_type->observers, OBJ_NODATA | OBJ_UNLINK, sorcery_observer_remove, callbacks); + ao2_callback(object_type->observers, OBJ_NODATA | OBJ_UNLINK, + sorcery_observer_remove, cbs); } diff --git a/res/res_pjsip/pjsip_configuration.c b/res/res_pjsip/pjsip_configuration.c index 835dbfbf69..8ee907ba7b 100644 --- a/res/res_pjsip/pjsip_configuration.c +++ b/res/res_pjsip/pjsip_configuration.c @@ -92,7 +92,7 @@ static void persistent_endpoint_contact_observer(const void *object) } /*! \brief Observer for contacts so state can be updated on respective endpoints */ -static struct ast_sorcery_observer state_contact_observer = { +static const struct ast_sorcery_observer state_contact_observer = { .created = persistent_endpoint_contact_observer, .deleted = persistent_endpoint_contact_observer, }; diff --git a/res/res_pjsip/pjsip_options.c b/res/res_pjsip/pjsip_options.c index c8c7843689..8d46eb0368 100644 --- a/res/res_pjsip/pjsip_options.c +++ b/res/res_pjsip/pjsip_options.c @@ -441,7 +441,7 @@ static void contact_deleted(const void *obj) } } -struct ast_sorcery_observer contact_observer = { +static const struct ast_sorcery_observer contact_observer = { .created = contact_created, .deleted = contact_deleted }; diff --git a/res/res_pjsip_registrar_expire.c b/res/res_pjsip_registrar_expire.c index 64f61ce413..53f34c614a 100644 --- a/res/res_pjsip_registrar_expire.c +++ b/res/res_pjsip_registrar_expire.c @@ -142,7 +142,7 @@ static void contact_expiration_observer_deleted(const void *object) } /*! \brief Observer callbacks for autoexpiring contacts */ -static struct ast_sorcery_observer contact_expiration_observer = { +static const struct ast_sorcery_observer contact_expiration_observer = { .created = contact_expiration_observer_created, .updated = contact_expiration_observer_updated, .deleted = contact_expiration_observer_deleted, diff --git a/tests/test_sorcery.c b/tests/test_sorcery.c index 6b64d99495..d2cd97c78f 100644 --- a/tests/test_sorcery.c +++ b/tests/test_sorcery.c @@ -227,7 +227,7 @@ static void sorcery_observer_loaded(const char *object_type) } /*! \brief Test sorcery observer implementation */ -static struct ast_sorcery_observer test_observer = { +static const struct ast_sorcery_observer test_observer = { .created = sorcery_observer_created, .updated = sorcery_observer_updated, .deleted = sorcery_observer_deleted, -- GitLab