[asterisk-commits] file: branch file/sorceryx3 r386189 - in /team/file/sorceryx3: include/asteri...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Sun Apr 21 17:22:59 CDT 2013
Author: file
Date: Sun Apr 21 17:22:57 2013
New Revision: 386189
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=386189
Log:
Add an observer callback for when an object type is loaded/reloaded.
Modified:
team/file/sorceryx3/include/asterisk/sorcery.h
team/file/sorceryx3/main/sorcery.c
team/file/sorceryx3/tests/test_sorcery.c
Modified: team/file/sorceryx3/include/asterisk/sorcery.h
URL: http://svnview.digium.com/svn/asterisk/team/file/sorceryx3/include/asterisk/sorcery.h?view=diff&rev=386189&r1=386188&r2=386189
==============================================================================
--- team/file/sorceryx3/include/asterisk/sorcery.h (original)
+++ team/file/sorceryx3/include/asterisk/sorcery.h Sun Apr 21 17:22:57 2013
@@ -237,6 +237,9 @@
/*! \brief Callback for when an object is deleted */
void (*deleted)(const void *object);
+
+ /*! \brief Callback for when an object type is loaded/reloaded */
+ void (*loaded)(const char *object_type);
};
/*! \brief Structure which contains details about a sorcery object */
Modified: team/file/sorceryx3/main/sorcery.c
URL: http://svnview.digium.com/svn/asterisk/team/file/sorceryx3/main/sorcery.c?view=diff&rev=386189&r1=386188&r2=386189
==============================================================================
--- team/file/sorceryx3/main/sorcery.c (original)
+++ team/file/sorceryx3/main/sorcery.c Sun Apr 21 17:22:57 2013
@@ -105,8 +105,8 @@
/*! \brief Structure used for observer invocations */
struct sorcery_observer_invocation {
- /*! \brief Pointer to the observers */
- struct ao2_container *observers;
+ /*! \brief Pointer to the object type */
+ struct ast_sorcery_object_type *object_type;
/*! \brief Pointer to the object */
void *object;
@@ -655,6 +655,58 @@
return 0;
}
+/*! \brief Destructor for observer invocation */
+static void sorcery_observer_invocation_destroy(void *obj)
+{
+ struct sorcery_observer_invocation *invocation = obj;
+
+ ao2_cleanup(invocation->object_type);
+ ao2_cleanup(invocation->object);
+}
+
+/*! \brief Allocator function for observer invocation */
+static struct sorcery_observer_invocation *sorcery_observer_invocation_alloc(struct ast_sorcery_object_type *object_type, void *object)
+{
+ struct sorcery_observer_invocation *invocation = ao2_alloc(sizeof(*invocation), sorcery_observer_invocation_destroy);
+
+ if (!invocation) {
+ return NULL;
+ }
+
+ ao2_ref(object_type, +1);
+ invocation->object_type = object_type;
+
+ if (object) {
+ ao2_ref(object, +1);
+ invocation->object = object;
+ }
+
+ return invocation;
+}
+
+/*! \brief Internal callback function which notifies an individual observer that an object type has been loaded */
+static int sorcery_observer_notify_loaded(void *obj, void *arg, int flags)
+{
+ const struct ast_sorcery_object_type_observer *observer = obj;
+
+ if (observer->callbacks->loaded) {
+ observer->callbacks->loaded(arg);
+ }
+
+ return 0;
+}
+
+/*! \brief Internal callback function which notifies observers that an object type has been loaded */
+static int sorcery_observers_notify_loaded(void *data)
+{
+ struct sorcery_observer_invocation *invocation = data;
+
+ ao2_callback(invocation->object_type->observers, OBJ_NODATA | OBJ_MULTIPLE, sorcery_observer_notify_loaded, invocation->object_type->name);
+ ao2_cleanup(invocation);
+
+ return 0;
+}
+
static int sorcery_object_load(void *obj, void *arg, int flags)
{
struct ast_sorcery_object_type *type = obj;
@@ -662,6 +714,14 @@
details->type = type->name;
ao2_callback(type->wizards, OBJ_NODATA, sorcery_wizard_load, details);
+
+ if (ao2_container_count(type->observers)) {
+ struct sorcery_observer_invocation *invocation = sorcery_observer_invocation_alloc(type, NULL);
+
+ if (invocation && ast_taskprocessor_push(type->serializer, sorcery_observers_notify_loaded, invocation)) {
+ ao2_cleanup(invocation);
+ }
+ }
return 0;
}
@@ -1135,32 +1195,6 @@
return (!object_wizard->caching && !object_wizard->wizard->create(details->sorcery, object_wizard->data, details->obj)) ? CMP_MATCH | CMP_STOP : 0;
}
-/*! \brief Destructor for observer invocation */
-static void sorcery_observer_invocation_destroy(void *obj)
-{
- struct sorcery_observer_invocation *invocation = obj;
-
- ao2_cleanup(invocation->observers);
- ao2_cleanup(invocation->object);
-}
-
-/*! \brief Allocator function for observer invocation */
-static struct sorcery_observer_invocation *sorcery_observer_invocation_alloc(struct ao2_container *observers, void *object)
-{
- struct sorcery_observer_invocation *invocation = ao2_alloc(sizeof(*invocation), sorcery_observer_invocation_destroy);
-
- if (!invocation) {
- return NULL;
- }
-
- ao2_ref(observers, +1);
- invocation->observers = observers;
- ao2_ref(object, +1);
- invocation->object = object;
-
- return invocation;
-}
-
/*! \brief Internal callback function which notifies an individual observer that an object has been created */
static int sorcery_observer_notify_create(void *obj, void *arg, int flags)
{
@@ -1178,7 +1212,7 @@
{
struct sorcery_observer_invocation *invocation = data;
- ao2_callback(invocation->observers, OBJ_NODATA | OBJ_MULTIPLE, sorcery_observer_notify_create, invocation->object);
+ ao2_callback(invocation->object_type->observers, OBJ_NODATA | OBJ_MULTIPLE, sorcery_observer_notify_create, invocation->object);
ao2_cleanup(invocation);
return 0;
@@ -1199,8 +1233,8 @@
}
if ((object_wizard = ao2_callback(object_type->wizards, 0, sorcery_wizard_create, &sdetails)) &&
- ao2_container_count(object_type->observers)) {
- struct sorcery_observer_invocation *invocation = sorcery_observer_invocation_alloc(object_type->observers, object);
+ ao2_container_count(object_type->observers)) {
+ struct sorcery_observer_invocation *invocation = sorcery_observer_invocation_alloc(object_type, object);
if (invocation && ast_taskprocessor_push(object_type->serializer, sorcery_observers_notify_create, invocation)) {
ao2_cleanup(invocation);
@@ -1227,7 +1261,7 @@
{
struct sorcery_observer_invocation *invocation = data;
- ao2_callback(invocation->observers, OBJ_NODATA | OBJ_MULTIPLE, sorcery_observer_notify_update, invocation->object);
+ ao2_callback(invocation->object_type->observers, OBJ_NODATA | OBJ_MULTIPLE, sorcery_observer_notify_update, invocation->object);
ao2_cleanup(invocation);
return 0;
@@ -1258,8 +1292,8 @@
}
if ((object_wizard = ao2_callback(object_type->wizards, 0, sorcery_wizard_update, &sdetails)) &&
- ao2_container_count(object_type->observers)) {
- struct sorcery_observer_invocation *invocation = sorcery_observer_invocation_alloc(object_type->observers, object);
+ ao2_container_count(object_type->observers)) {
+ struct sorcery_observer_invocation *invocation = sorcery_observer_invocation_alloc(object_type, object);
if (invocation && ast_taskprocessor_push(object_type->serializer, sorcery_observers_notify_update, invocation)) {
ao2_cleanup(invocation);
@@ -1286,7 +1320,7 @@
{
struct sorcery_observer_invocation *invocation = data;
- ao2_callback(invocation->observers, OBJ_NODATA | OBJ_MULTIPLE, sorcery_observer_notify_delete, invocation->object);
+ ao2_callback(invocation->object_type->observers, OBJ_NODATA | OBJ_MULTIPLE, sorcery_observer_notify_delete, invocation->object);
ao2_cleanup(invocation);
return 0;
@@ -1317,8 +1351,8 @@
}
if ((object_wizard = ao2_callback(object_type->wizards, 0, sorcery_wizard_delete, &sdetails)) &&
- ao2_container_count(object_type->observers)) {
- struct sorcery_observer_invocation *invocation = sorcery_observer_invocation_alloc(object_type->observers, object);
+ ao2_container_count(object_type->observers)) {
+ struct sorcery_observer_invocation *invocation = sorcery_observer_invocation_alloc(object_type, object);
if (invocation && ast_taskprocessor_push(object_type->serializer, sorcery_observers_notify_delete, invocation)) {
ao2_cleanup(invocation);
Modified: team/file/sorceryx3/tests/test_sorcery.c
URL: http://svnview.digium.com/svn/asterisk/team/file/sorceryx3/tests/test_sorcery.c?view=diff&rev=386189&r1=386188&r2=386189
==============================================================================
--- team/file/sorceryx3/tests/test_sorcery.c (original)
+++ team/file/sorceryx3/tests/test_sorcery.c Sun Apr 21 17:22:57 2013
@@ -143,6 +143,9 @@
/*! \brief Pointer to the deleted object */
const void *deleted;
+
+ /*! \brief Whether the type has been loaded */
+ unsigned int loaded:1;
};
/*! \brief Global scope apply handler integer to make sure it executed */
@@ -215,11 +218,19 @@
ast_cond_signal(&observer.cond);
}
+static void sorcery_observer_loaded(const char *object_type)
+{
+ SCOPED_MUTEX(lock, &observer.lock);
+ observer.loaded = 1;
+ ast_cond_signal(&observer.cond);
+}
+
/*! \brief Test sorcery observer implementation */
static struct ast_sorcery_observer test_observer = {
.created = sorcery_observer_created,
.updated = sorcery_observer_updated,
.deleted = sorcery_observer_deleted,
+ .loaded = sorcery_observer_loaded,
};
static struct ast_sorcery *alloc_and_initialize_sorcery(void)
@@ -2166,6 +2177,26 @@
if (!observer.deleted) {
ast_test_status_update(test, "Failed to receive observer notification for object deletion within suitable timeframe\n");
+ goto end;
+ }
+
+ ast_sorcery_reload(sorcery);
+
+ ast_mutex_lock(&observer.lock);
+ while (!observer.loaded) {
+ struct timeval start = ast_tvnow();
+ struct timespec end = {
+ .tv_sec = start.tv_sec + 10,
+ .tv_nsec = start.tv_usec * 1000,
+ };
+ if (ast_cond_timedwait(&observer.cond, &observer.lock, &end) == ETIMEDOUT) {
+ break;
+ }
+ }
+ ast_mutex_unlock(&observer.lock);
+
+ if (!observer.loaded) {
+ ast_test_status_update(test, "Failed to receive observer notification for object type load within suitable timeframe\n");
goto end;
}
More information about the asterisk-commits
mailing list