diff options
author | Matt Jordan <mjordan@digium.com> | 2015-07-04 10:03:06 -0500 |
---|---|---|
committer | Matt Jordan <mjordan@digium.com> | 2015-07-04 20:32:09 -0500 |
commit | b178f8701bee0b56b3648a3c63bff1cd8ee0bc6d (patch) | |
tree | 25de93b965b5b078418e01ce3b6012f7a0573424 /main/sorcery.c | |
parent | 987548413d05af0f29089e3d54cb277b5d2156c4 (diff) |
sorcery: Add support for object staleness
This patch enhances the sorcery API to allow for sorcery wizards to
determine if an object is stale. This includes the following:
* Sorcery objects now have a timestamp that is set on creation. Since
sorcery objects are immutable, this can be used by sorcery wizards to
determine if an object is stale.
* A new API call has been added, ast_sorcery_is_stale. This API call
queries the wizards associated with the object, calling a new callback
function 'is_stale'. Note that if a wizard does not support the new
callback, objects are always assumed to not be stale.
* Unit tests have been added that cover the new API call.
Change-Id: Ica93c6a4e8a06c0376ea43e00cf702920b806064
Diffstat (limited to 'main/sorcery.c')
-rw-r--r-- | main/sorcery.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/main/sorcery.c b/main/sorcery.c index 20b3d6b2f..fbbd14662 100644 --- a/main/sorcery.c +++ b/main/sorcery.c @@ -129,6 +129,9 @@ struct ast_sorcery_object { /*! \brief Extended object fields */ struct ast_variable *extended; + + /*! \brief Time that the object was created */ + struct timeval created; }; /*! \brief Structure for registered object type */ @@ -1734,6 +1737,7 @@ void *ast_sorcery_alloc(const struct ast_sorcery *sorcery, const char *type, con details->object->id = ast_strdup(id); } + details->object->created = ast_tvnow(); ast_copy_string(details->object->type, type, sizeof(details->object->type)); if (aco_set_defaults(&object_type->type, id, details)) { @@ -2143,6 +2147,35 @@ int ast_sorcery_delete(const struct ast_sorcery *sorcery, void *object) return object_wizard ? 0 : -1; } +int ast_sorcery_is_stale(const struct ast_sorcery *sorcery, void *object) +{ + const struct ast_sorcery_object_details *details = object; + RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, details->object->type, OBJ_KEY), ao2_cleanup); + struct ast_sorcery_object_wizard *found_wizard; + int res = 0; + int i; + + if (!object_type) { + return -1; + } + + AST_VECTOR_RW_RDLOCK(&object_type->wizards); + for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) { + found_wizard = AST_VECTOR_GET(&object_type->wizards, i); + + if (found_wizard->wizard->callbacks.is_stale) { + res |= found_wizard->wizard->callbacks.is_stale(sorcery, found_wizard->data, object); + ast_debug(5, "After calling wizard '%s', object '%s' is %s\n", + found_wizard->wizard->callbacks.name, + ast_sorcery_object_get_id(object), + res ? "stale" : "not stale"); + } + } + AST_VECTOR_RW_UNLOCK(&object_type->wizards); + + return res; +} + void ast_sorcery_unref(struct ast_sorcery *sorcery) { if (sorcery) { @@ -2161,6 +2194,12 @@ const char *ast_sorcery_object_get_id(const void *object) return details->object->id; } +const struct timeval ast_sorcery_object_get_created(const void *object) +{ + const struct ast_sorcery_object_details *details = object; + return details->object->created; +} + const char *ast_sorcery_object_get_type(const void *object) { const struct ast_sorcery_object_details *details = object; |