summaryrefslogtreecommitdiff
path: root/main/astobj2_container.c
diff options
context:
space:
mode:
authorCorey Farrell <git@cfware.com>2017-10-09 18:51:05 -0400
committerCorey Farrell <git@cfware.com>2017-10-10 20:17:09 -0400
commite54238388de65410b0321a321cb2796946f71113 (patch)
treef4dae1412a2cf298bcbf9d9a5822d4739bbffa13 /main/astobj2_container.c
parent0727a8e5242f4493ff3d7375e6996924cd00cbea (diff)
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
Diffstat (limited to 'main/astobj2_container.c')
-rw-r--r--main/astobj2_container.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/main/astobj2_container.c b/main/astobj2_container.c
index a978db3d4..c75dff991 100644
--- a/main/astobj2_container.c
+++ b/main/astobj2_container.c
@@ -437,6 +437,48 @@ void *__ao2_find(struct ao2_container *c, const void *arg, enum search_flags fla
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,
+ const char *tag, const char *file, int line, const char *func)
+{
+ void *proxy;
+ void *obj = NULL;
+ enum ao2_lock_req orig_lock;
+
+ ast_assert(!!c);
+ ast_assert(flags & OBJ_SEARCH_MASK);
+ ast_assert(!(flags & ~(OBJ_SEARCH_MASK | OBJ_NOLOCK)));
+
+ if (flags & OBJ_NOLOCK) {
+ orig_lock = __adjust_lock(c, AO2_LOCK_REQ_RDLOCK, 1);
+ } else {
+ orig_lock = AO2_LOCK_REQ_RDLOCK;
+ ao2_rdlock(c);
+ }
+
+ while ((proxy = ao2_find(c, arg, flags | OBJ_NOLOCK))) {
+ obj = __ao2_weakproxy_get_object(proxy, 0, tag ?: __PRETTY_FUNCTION__, file, line, func);
+
+ if (obj) {
+ ao2_ref(proxy, -1);
+ break;
+ }
+
+ /* Upgrade to a write lock */
+ __adjust_lock(c, AO2_LOCK_REQ_WRLOCK, 1);
+ ao2_unlink_flags(c, proxy, OBJ_NOLOCK);
+ ao2_ref(proxy, -1);
+ }
+
+ if (flags & OBJ_NOLOCK) {
+ /* We'll keep any upgraded lock */
+ __adjust_lock(c, orig_lock, 1);
+ } else {
+ ao2_unlock(c);
+ }
+
+ return obj;
+}
+
/*!
* initialize an iterator so we start from the first object
*/