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
This commit is contained in:
Richard Mudgett
2013-12-03 17:35:54 +00:00
parent 8e8b329e14
commit 3357c494cb
8 changed files with 26 additions and 15 deletions

View File

@@ -256,7 +256,7 @@ int ast_bucket_observer_add(const struct ast_sorcery_observer *callbacks);
* *
* \param callbacks Implementation of the sorcery observer interface * \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 * \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 * \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 * \brief Get a JSON representation of a bucket file

View File

@@ -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 sorcery Pointer to a sorcery structure
* \param type Type of object * \param type Type of object
* \param hidden All objects of this type are internal and should not be manipulated by users * \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 alloc Required object allocation callback
* \param transform Optional transformation callback * \param transform Optional transformation callback
* \param apply Optional object set apply 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 0 success
* \retval -1 failure * \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 * \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 sorcery Pointer to a sorcery structure
* \param type Type of object to retrieve * \param type Type of object to retrieve
* \param flags Flags to control behavior * \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 non-NULL if found
* \retval NULL if not found * \retval NULL if not found

View File

@@ -473,7 +473,7 @@ int ast_bucket_observer_add(const struct ast_sorcery_observer *callbacks)
return ast_sorcery_observer_add(bucket_sorcery, "bucket", 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); 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); 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); ast_sorcery_observer_remove(bucket_sorcery, "file", callbacks);
} }

View File

@@ -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); 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; struct ast_sorcery_object_type_observer *observer;
int res;
if (!object_type || !callbacks) { if (!object_type || !callbacks) {
return -1; return -1;
@@ -1536,10 +1537,13 @@ int ast_sorcery_observer_add(const struct ast_sorcery *sorcery, const char *type
} }
observer->callbacks = callbacks; observer->callbacks = callbacks;
ao2_link(object_type->observers, observer); res = 0;
if (!ao2_link(object_type->observers, observer)) {
res = -1;
}
ao2_ref(observer, -1); ao2_ref(observer, -1);
return 0; return res;
} }
/*! \brief Internal callback function for removing an observer */ /*! \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; 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) { if (!object_type) {
return; 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);
} }

View File

@@ -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 */ /*! \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, .created = persistent_endpoint_contact_observer,
.deleted = persistent_endpoint_contact_observer, .deleted = persistent_endpoint_contact_observer,
}; };

View File

@@ -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, .created = contact_created,
.deleted = contact_deleted .deleted = contact_deleted
}; };

View File

@@ -142,7 +142,7 @@ static void contact_expiration_observer_deleted(const void *object)
} }
/*! \brief Observer callbacks for autoexpiring contacts */ /*! \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, .created = contact_expiration_observer_created,
.updated = contact_expiration_observer_updated, .updated = contact_expiration_observer_updated,
.deleted = contact_expiration_observer_deleted, .deleted = contact_expiration_observer_deleted,

View File

@@ -227,7 +227,7 @@ static void sorcery_observer_loaded(const char *object_type)
} }
/*! \brief Test sorcery observer implementation */ /*! \brief Test sorcery observer implementation */
static struct ast_sorcery_observer test_observer = { static const struct ast_sorcery_observer test_observer = {
.created = sorcery_observer_created, .created = sorcery_observer_created,
.updated = sorcery_observer_updated, .updated = sorcery_observer_updated,
.deleted = sorcery_observer_deleted, .deleted = sorcery_observer_deleted,