<p>Corey Farrell has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/6710">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">astobj2: Add ao2_weakproxy_find function.<br><br>This function finds a weak proxy in an ao2_container and returns the<br>real object associated with it.<br><br>Change-Id: I9da822049747275f5961b5c0a7f14e87157d65d8<br>---<br>M include/asterisk/astobj2.h<br>M main/astobj2_container.c<br>2 files changed, 76 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/10/6710/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/include/asterisk/astobj2.h b/include/asterisk/astobj2.h<br>index 484e1e3..8457c8e 100644<br>--- a/include/asterisk/astobj2.h<br>+++ b/include/asterisk/astobj2.h<br>@@ -1771,6 +1771,25 @@<br> void *__ao2_find(struct ao2_container *c, const void *arg, enum search_flags flags,<br>  const char *tag, const char *file, int line, const char *func);<br> <br>+/*!<br>+ * \brief Perform an ao2_find on a container with ao2_weakproxy objects, returning the real object.<br>+ * \param ret -1 on error, 0 on success.<br>+ * \return The object found or NULL if none found.<br>+ *<br>+ * \note Only OBJ_SEARCH_* and OBJ_NOLOCK flags are supported by this function.<br>+ * \note OBJ_NOLOCK should be used when this function is called as part of a find_or_create.<br>+ *       OBJ_NOLOCK is used when the caller already has a lock on the container.  It skips the<br>+ *       initial lock and the final unlock.<br>+ * \note when ret is -1 it is unknown if a matching object already exists.<br>+ * \warning This function will unlock then relock the container if a matching weakproxy is<br>+ *          found, regardless of the OBJ_NOLOCK flag.<br>+ * \see ao2_callback for description of arguments.<br>+ */<br>+#define ao2_weakproxy_find(c, arg, flags, result, tag) \<br>+  __ao2_weakproxy_find(c, arg, flags, result, tag, __FILE__, __LINE__, __PRETTY_FUNCTION__)<br>+void *__ao2_weakproxy_find(struct ao2_container *c, const void *arg, enum search_flags flags,<br>+    int *ret, const char *tag, const char *file, int line, const char *func);<br>+<br> /*! \brief<br>  *<br>  *<br>diff --git a/main/astobj2_container.c b/main/astobj2_container.c<br>index a978db3..dc26639 100644<br>--- a/main/astobj2_container.c<br>+++ b/main/astobj2_container.c<br>@@ -437,6 +437,63 @@<br>    return __ao2_callback(c, flags, c->cmp_fn, arged, tag, file, line, func);<br> }<br> <br>+void *__ao2_weakproxy_find(struct ao2_container *c, const void *arg, enum search_flags flags,<br>+  int *ret, const char *tag, const char *file, int line, const char *func)<br>+{<br>+ void *proxy;<br>+ int tries = 0;<br>+       int fake_ret;<br>+<br>+     ast_assert(!!c);<br>+     ast_assert(flags & OBJ_SEARCH_MASK);<br>+     ast_assert(!(flags & ~(OBJ_SEARCH_MASK | OBJ_NOLOCK)));<br>+<br>+       if (!ret) {<br>+          /* This should not be used by a find_or_create method. */<br>+            ret = &fake_ret;<br>+ }<br>+<br>+ *ret = 0;<br>+<br>+ if (!(flags & OBJ_NOLOCK)) {<br>+             ao2_lock(c);<br>+ }<br>+<br>+ while ((proxy = ao2_find(c, arg, flags | OBJ_NOLOCK))) {<br>+             void *obj;<br>+<br>+                /* Never lock proxy while instances is already locked. */<br>+            ao2_unlock(c);<br>+               obj = __ao2_weakproxy_get_object(proxy, 0, tag ?: __PRETTY_FUNCTION__, file, line, func);<br>+            ao2_lock(c);<br>+<br>+              if (obj) {<br>+                   /* We have an existing object and it's not being destroyed. */<br>+                   ao2_ref(proxy, -1);<br>+<br>+                       return obj;<br>+          }<br>+<br>+         /* the old proxy is being destroyed, clean list before creating/adding new one */<br>+            ao2_unlink_flags(c, proxy, OBJ_NOLOCK);<br>+              ao2_ref(proxy, -1);<br>+<br>+               if (tries >= 3) {<br>+                 /* Unlikely but not impossible.  Bail to avoid infinate loop. */<br>+                     *ret = -1;<br>+                   break;<br>+               }<br>+<br>+         tries++;<br>+     }<br>+<br>+ if (!(flags & OBJ_NOLOCK)) {<br>+             ao2_unlock(c);<br>+       }<br>+<br>+ return NULL;<br>+}<br>+<br> /*!<br>  * initialize an iterator so we start from the first object<br>  */<br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/6710">change 6710</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/6710"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I9da822049747275f5961b5c0a7f14e87157d65d8 </div>
<div style="display:none"> Gerrit-Change-Number: 6710 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Corey Farrell <git@cfware.com> </div>