<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>