[Asterisk-code-review] Astobj2: Add ao2 weakproxy ref object function. (asterisk[master])

Corey Farrell asteriskteam at digium.com
Wed Apr 29 05:00:38 CDT 2015


Corey Farrell has uploaded a new change for review.

  https://gerrit.asterisk.org/280

Change subject: Astobj2: Add ao2_weakproxy_ref_object function.
......................................................................

Astobj2: Add ao2_weakproxy_ref_object function.

This function allows code to run ao2_ref against the real
object associated with a weakproxy.  It is useful when
all of the following conditions are true:
* You have a pointer to weakproxy.
* You do not have or need a pointer to the real object.
* You need to ensure the real object exists and is not
  destroyed during a process.

In this case it's wasteful to store a pointer to the real
object just for the sake of releasing it later.

Change-Id: I38a319b83314de75be74207a8771aab269bcca46
---
M include/asterisk/astobj2.h
M main/astobj2.c
M tests/test_astobj2_weaken.c
3 files changed, 85 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/80/280/1

diff --git a/include/asterisk/astobj2.h b/include/asterisk/astobj2.h
index de35bb3..7e2c59d 100644
--- a/include/asterisk/astobj2.h
+++ b/include/asterisk/astobj2.h
@@ -560,6 +560,32 @@
 
 /*!
  * \since 14.0.0
+ * \brief Run ao2_t_ref on the object associated with weakproxy.
+ *
+ * \param weakproxy The weakproxy to read from.
+ * \param delta Value to add to the reference counter.
+ * \param flags OBJ_NOLOCK to avoid locking weakproxy.
+ *
+ * \retval -2 weakproxy is not a valid ao2_weakproxy.
+ * \retval -1 weakproxy has no associated object.
+ *
+ * \return The value of the reference counter before the operation.
+ *
+ * \note The OBJ_NOLOCK flag is only effective for delta >= 0.  For negative
+ *       delta's weakproxy will be locked by ao2_ref.
+ */
+int __ao2_weakproxy_ref_object(void *weakproxy, int delta, int flags,
+	const char *tag, const char *file, int line, const char *func);
+
+#define ao2_t_weakproxy_ref_object(weakproxy, delta, flags, tag) \
+	__ao2_weakproxy_ref_object(weakproxy, delta, flags, \
+		tag, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+#define ao2_weakproxy_ref_object(weakproxy, delta, flags) \
+	ao2_t_weakproxy_ref_object(weakproxy, delta, flags, "")
+
+/*!
+ * \since 14.0.0
  * \brief Get the object associated with weakproxy.
  *
  * \param weakproxy The weakproxy to read from.
diff --git a/main/astobj2.c b/main/astobj2.c
index c5b5cd9..0a1ae12 100644
--- a/main/astobj2.c
+++ b/main/astobj2.c
@@ -836,6 +836,37 @@
 	return ret;
 }
 
+int __ao2_weakproxy_ref_object(void *weakproxy, int delta, int flags,
+	const char *tag, const char *file, int line, const char *func)
+{
+	struct astobj2 *internal = NULL;
+	int ret = -1;
+
+	if (weakproxy) {
+		internal = __INTERNAL_OBJ_CHECK(weakproxy, file, line, func);
+	}
+
+	if (!internal || internal->priv_data.magic != AO2_WEAK) {
+		/* This method is meant to be run on weakproxy objects! */
+		return -2;
+	}
+
+	/* We have a weak object, grab lock if needed. */
+	if (delta >= 0 && !(flags & OBJ_NOLOCK)) {
+		ao2_lock(weakproxy);
+	}
+
+	if (internal->priv_data.weakptr) {
+		ret = __ao2_ref(internal->priv_data.weakptr, delta, tag, file, line, func);
+	}
+
+	if (delta >= 0 && !(flags & OBJ_NOLOCK)) {
+		ao2_unlock(weakproxy);
+	}
+
+	return ret;
+}
+
 void *__ao2_weakproxy_get_object(void *weakproxy, int flags,
 	const char *tag, const char *file, int line, const char *func)
 {
diff --git a/tests/test_astobj2_weaken.c b/tests/test_astobj2_weaken.c
index e53ab7a..0d7c9c6 100644
--- a/tests/test_astobj2_weaken.c
+++ b/tests/test_astobj2_weaken.c
@@ -223,7 +223,29 @@
 		goto fail_cleanup;
 	}
 
+	if (ao2_t_weakproxy_ref_object(obj3, +1, 0, "ao2_ref should never see this") != -2) {
+		ast_test_status_update(test,
+			"Expected -2 from ao2_t_weakproxy_ref_object against normal ao2 object.\n");
+		goto fail_cleanup;
+	}
+
+	if (ao2_t_weakproxy_ref_object(weakref2, +1, 0, "weakref2 ref_object") != 2) {
+		ast_test_status_update(test, "Expected 2 from weakref2 ref_object.\n");
+		goto fail_cleanup;
+	}
+
+	if (ao2_t_ref(obj3, -1, "balance weakref2 ref_object") != 3) {
+		ast_test_status_update(test, "Expected 3 from obj3 ao2_t_ref.\n");
+		goto fail_cleanup;
+	}
+
 	ao2_ref(obj3, -1);
+
+	if (ao2_weakproxy_ref_object(weakref2, +1, 0) != -1) {
+		ast_test_status_update(test, "Expected -1 from weakref2 ref_object because obj3 is gone.\n");
+		goto fail_cleanup;
+	}
+
 	ao2_t_ref(weakref2, -1, "weakref2");
 
 	if (!weakproxydestroyed) {
@@ -231,6 +253,12 @@
 		return AST_TEST_FAIL;
 	}
 
+	if (ao2_weakproxy_ref_object(NULL, +1, 0) != -2) {
+		ast_test_status_update(test,
+			"Expected -2 from ao2_t_weakproxy_ref_object against NULL.\n");
+		goto fail_cleanup;
+	}
+
 	return AST_TEST_PASS;
 
 fail_cleanup:

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I38a319b83314de75be74207a8771aab269bcca46
Gerrit-PatchSet: 1
Gerrit-Project: asterisk
Gerrit-Branch: master
Gerrit-Owner: Corey Farrell <git at cfware.com>



More information about the asterisk-code-review mailing list