<p>Corey Farrell has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/6745">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">sorcery: Use ao2_weakproxy to hold list of instances.<br><br>Store weak proxy objects in instances container.<br><br>Change-Id: I5a150a4e13cee319d46b5a4654f95a4623a978f8<br>---<br>M main/sorcery.c<br>1 file changed, 59 insertions(+), 31 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/45/6745/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/main/sorcery.c b/main/sorcery.c<br>index 5d0b38f..c185fc7 100644<br>--- a/main/sorcery.c<br>+++ b/main/sorcery.c<br>@@ -209,6 +209,13 @@<br> intptr_t args[];<br> };<br> <br>+/*! \brief Proxy object for sorcery */<br>+struct sorcery_proxy {<br>+ AO2_WEAKPROXY();<br>+ /*! \brief The name of the module owning this sorcery instance */<br>+ char module_name[0];<br>+};<br>+<br> /*! \brief Full structure for sorcery */<br> struct ast_sorcery {<br> /*! \brief Container for known object types */<br>@@ -217,8 +224,8 @@<br> /*! \brief Observers */<br> struct ao2_container *observers;<br> <br>- /*! \brief The name of the module owning this sorcery instance */<br>- char module_name[0];<br>+ /*! \brief Pointer to module_name in the associated sorcery_proxy. */<br>+ char *module_name;<br> };<br> <br> /*! \brief Structure for passing load/reload details */<br>@@ -451,8 +458,8 @@<br> /*! \brief Compare function for sorcery instances */<br> static int sorcery_instance_cmp(void *obj, void *arg, int flags)<br> {<br>- const struct ast_sorcery *object_left = obj;<br>- const struct ast_sorcery *object_right = arg;<br>+ const struct sorcery_proxy *object_left = obj;<br>+ const struct sorcery_proxy *object_right = arg;<br> const char *right_key = arg;<br> int cmp;<br> <br>@@ -479,7 +486,7 @@<br> /*! \brief Hashing function for sorcery instances */<br> static int sorcery_instance_hash(const void *obj, const int flags)<br> {<br>- const struct ast_sorcery *object;<br>+ const struct sorcery_proxy *object;<br> const char *key;<br> <br> switch (flags & OBJ_SEARCH_MASK) {<br>@@ -754,55 +761,83 @@<br> return CMP_MATCH;<br> }<br> <br>+static void sorcery_proxy_cb(void *weakproxy, void *data)<br>+{<br>+ ao2_unlink(instances, weakproxy);<br>+}<br>+<br> struct ast_sorcery *__ast_sorcery_open(const char *module_name)<br> {<br>+ struct sorcery_proxy *proxy;<br> struct ast_sorcery *sorcery;<br> <br> ast_assert(module_name != NULL);<br> <br> ao2_wrlock(instances);<br>- if ((sorcery = ao2_find(instances, module_name, OBJ_SEARCH_KEY | OBJ_NOLOCK))) {<br>- goto done;<br>+ sorcery = ao2_weakproxy_find(instances, module_name, OBJ_SEARCH_KEY | OBJ_NOLOCK,<br>+ __PRETTY_FUNCTION__);<br>+ if (sorcery) {<br>+ ao2_unlock(instances);<br>+<br>+ return sorcery;<br> }<br> <br>- if (!(sorcery = ao2_alloc(sizeof(*sorcery) + strlen(module_name) + 1, sorcery_destructor))) {<br>- goto done;<br>+ proxy = ao2_t_weakproxy_alloc(sizeof(*proxy) + strlen(module_name) + 1, NULL, module_name);<br>+ if (!proxy) {<br>+ goto failure_cleanup;<br>+ }<br>+ strcpy(proxy->module_name, module_name); /* Safe */<br>+<br>+ sorcery = ao2_t_alloc(sizeof(*sorcery), sorcery_destructor, module_name);<br>+ if (!sorcery) {<br>+ goto failure_cleanup;<br>+ }<br>+<br>+ sorcery->module_name = proxy->module_name;<br>+<br>+ /* We have exclusive access to proxy and sorcery, no need for locking here. */<br>+ if (ao2_t_weakproxy_set_object(proxy, sorcery, OBJ_NOLOCK, "weakproxy link")) {<br>+ goto failure_cleanup;<br>+ }<br>+<br>+ if (ao2_weakproxy_subscribe(proxy, sorcery_proxy_cb, NULL, OBJ_NOLOCK)) {<br>+ goto failure_cleanup;<br> }<br> <br> if (!(sorcery->types = ao2_container_alloc_options(AO2_ALLOC_OPT_LOCK_RWLOCK, TYPE_BUCKETS, sorcery_type_hash, sorcery_type_cmp))) {<br>- ao2_ref(sorcery, -1);<br>- sorcery = NULL;<br>- goto done;<br>+ goto failure_cleanup;<br> }<br> <br> if (!(sorcery->observers = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_RWLOCK, 0, NULL, NULL))) {<br>- ao2_ref(sorcery, -1);<br>- sorcery = NULL;<br>- goto done;<br>+ goto failure_cleanup;<br> }<br>-<br>- strcpy(sorcery->module_name, module_name); /* Safe */<br> <br> if (__ast_sorcery_apply_config(sorcery, module_name, module_name) == AST_SORCERY_APPLY_FAIL) {<br> ast_log(LOG_ERROR, "Error attempting to apply configuration %s to sorcery.\n", module_name);<br>- ao2_cleanup(sorcery);<br>- sorcery = NULL;<br>- goto done;<br>+ goto failure_cleanup;<br> }<br> <br>- ao2_link_flags(instances, sorcery, OBJ_NOLOCK);<br>+ ao2_link_flags(instances, proxy, OBJ_NOLOCK);<br>+ ao2_ref(proxy, -1);<br> <br> NOTIFY_GLOBAL_OBSERVERS(observers, instance_created, module_name, sorcery);<br> <br>-done:<br> ao2_unlock(instances);<br> return sorcery;<br>+<br>+failure_cleanup:<br>+ /* cleanup of sorcery may result in locking instances, so make sure we unlock first. */<br>+ ao2_unlock(instances);<br>+ ao2_cleanup(sorcery);<br>+ ao2_cleanup(proxy);<br>+<br>+ return NULL;<br> }<br> <br> /*! \brief Search function for sorcery instances */<br> struct ast_sorcery *ast_sorcery_retrieve_by_module_name(const char *module_name)<br> {<br>- return ao2_find(instances, module_name, OBJ_SEARCH_KEY);<br>+ return ao2_weakproxy_find(instances, module_name, OBJ_SEARCH_KEY, "");<br> }<br> <br> /*! \brief Destructor function for object types */<br>@@ -2297,14 +2332,7 @@<br> <br> void ast_sorcery_unref(struct ast_sorcery *sorcery)<br> {<br>- if (sorcery) {<br>- /* One ref for what we just released, the other for the instances container. */<br>- ao2_wrlock(instances);<br>- if (ao2_ref(sorcery, -1) == 2) {<br>- ao2_unlink_flags(instances, sorcery, OBJ_NOLOCK);<br>- }<br>- ao2_unlock(instances);<br>- }<br>+ ao2_cleanup(sorcery);<br> }<br> <br> const char *ast_sorcery_object_get_id(const void *object)<br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/6745">change 6745</a>. To unsubscribe, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/6745"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 14 </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I5a150a4e13cee319d46b5a4654f95a4623a978f8 </div>
<div style="display:none"> Gerrit-Change-Number: 6745 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Corey Farrell <git@cfware.com> </div>