[Asterisk-code-review] astobj2: Add ao2 weakproxy find function. (asterisk[master])

Corey Farrell asteriskteam at digium.com
Mon Oct 9 22:42:40 CDT 2017


Corey Farrell has uploaded this change for review. ( https://gerrit.asterisk.org/6710


Change subject: astobj2: Add ao2_weakproxy_find function.
......................................................................

astobj2: Add ao2_weakproxy_find function.

This function finds a weak proxy in an ao2_container and returns the
real object associated with it.

Change-Id: I9da822049747275f5961b5c0a7f14e87157d65d8
---
M include/asterisk/astobj2.h
M main/astobj2_container.c
2 files changed, 76 insertions(+), 0 deletions(-)



  git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/10/6710/1

diff --git a/include/asterisk/astobj2.h b/include/asterisk/astobj2.h
index 484e1e3..8457c8e 100644
--- a/include/asterisk/astobj2.h
+++ b/include/asterisk/astobj2.h
@@ -1771,6 +1771,25 @@
 void *__ao2_find(struct ao2_container *c, const void *arg, enum search_flags flags,
 	const char *tag, const char *file, int line, const char *func);
 
+/*!
+ * \brief Perform an ao2_find on a container with ao2_weakproxy objects, returning the real object.
+ * \param ret -1 on error, 0 on success.
+ * \return The object found or NULL if none found.
+ *
+ * \note Only OBJ_SEARCH_* and OBJ_NOLOCK flags are supported by this function.
+ * \note OBJ_NOLOCK should be used when this function is called as part of a find_or_create.
+ *       OBJ_NOLOCK is used when the caller already has a lock on the container.  It skips the
+ *       initial lock and the final unlock.
+ * \note when ret is -1 it is unknown if a matching object already exists.
+ * \warning This function will unlock then relock the container if a matching weakproxy is
+ *          found, regardless of the OBJ_NOLOCK flag.
+ * \see ao2_callback for description of arguments.
+ */
+#define ao2_weakproxy_find(c, arg, flags, result, tag) \
+	__ao2_weakproxy_find(c, arg, flags, result, tag, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+void *__ao2_weakproxy_find(struct ao2_container *c, const void *arg, enum search_flags flags,
+	int *ret, const char *tag, const char *file, int line, const char *func);
+
 /*! \brief
  *
  *
diff --git a/main/astobj2_container.c b/main/astobj2_container.c
index a978db3..dc26639 100644
--- a/main/astobj2_container.c
+++ b/main/astobj2_container.c
@@ -437,6 +437,63 @@
 	return __ao2_callback(c, flags, c->cmp_fn, arged, tag, file, line, func);
 }
 
+void *__ao2_weakproxy_find(struct ao2_container *c, const void *arg, enum search_flags flags,
+	int *ret, const char *tag, const char *file, int line, const char *func)
+{
+	void *proxy;
+	int tries = 0;
+	int fake_ret;
+
+	ast_assert(!!c);
+	ast_assert(flags & OBJ_SEARCH_MASK);
+	ast_assert(!(flags & ~(OBJ_SEARCH_MASK | OBJ_NOLOCK)));
+
+	if (!ret) {
+		/* This should not be used by a find_or_create method. */
+		ret = &fake_ret;
+	}
+
+	*ret = 0;
+
+	if (!(flags & OBJ_NOLOCK)) {
+		ao2_lock(c);
+	}
+
+	while ((proxy = ao2_find(c, arg, flags | OBJ_NOLOCK))) {
+		void *obj;
+
+		/* Never lock proxy while instances is already locked. */
+		ao2_unlock(c);
+		obj = __ao2_weakproxy_get_object(proxy, 0, tag ?: __PRETTY_FUNCTION__, file, line, func);
+		ao2_lock(c);
+
+		if (obj) {
+			/* We have an existing object and it's not being destroyed. */
+			ao2_ref(proxy, -1);
+
+			return obj;
+		}
+
+		/* the old proxy is being destroyed, clean list before creating/adding new one */
+		ao2_unlink_flags(c, proxy, OBJ_NOLOCK);
+		ao2_ref(proxy, -1);
+
+		if (tries >= 3) {
+			/* Unlikely but not impossible.  Bail to avoid infinate loop. */
+			*ret = -1;
+			break;
+		}
+
+		tries++;
+	}
+
+	if (!(flags & OBJ_NOLOCK)) {
+		ao2_unlock(c);
+	}
+
+	return NULL;
+}
+
 /*!
  * initialize an iterator so we start from the first object
  */

-- 
To view, visit https://gerrit.asterisk.org/6710
To unsubscribe, visit https://gerrit.asterisk.org/settings

Gerrit-Project: asterisk
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I9da822049747275f5961b5c0a7f14e87157d65d8
Gerrit-Change-Number: 6710
Gerrit-PatchSet: 1
Gerrit-Owner: Corey Farrell <git at cfware.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20171009/1a85e16d/attachment-0001.html>


More information about the asterisk-code-review mailing list