<p>Jenkins2 <strong>merged</strong> this change.</p><p><a href="https://gerrit.asterisk.org/6745">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Richard Mudgett: Looks good to me, but someone else must approve
  Joshua Colp: Looks good to me, but someone else must approve
  George Joseph: Looks good to me, approved
  Jenkins2: Approved for Submit

</div><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;">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: merged </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>
<div style="display:none"> Gerrit-Reviewer: George Joseph <gjoseph@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins2 </div>
<div style="display:none"> Gerrit-Reviewer: Joshua Colp <jcolp@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Richard Mudgett <rmudgett@digium.com> </div>