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
changes/80/280/3
Corey Farrell 10 years ago
parent ed5715eb39
commit c9c03998cc

@ -558,6 +558,29 @@ int __ao2_weakproxy_set_object(void *weakproxy, void *obj, int flags,
#define ao2_t_weakproxy_set_object(weakproxy, obj, flags, tag) \
__ao2_weakproxy_set_object(weakproxy, obj, flags, tag, __FILE__, __LINE__, __PRETTY_FUNCTION__)
/*!
* \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.
*/
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.

@ -836,6 +836,33 @@ int __ao2_weakproxy_set_object(void *weakproxy, void *obj, int flags,
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 = __INTERNAL_OBJ_CHECK(weakproxy, file, line, func);
int ret = -1;
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 (!(flags & OBJ_NOLOCK)) {
ao2_lock(weakproxy);
}
if (internal->priv_data.weakptr) {
ret = __ao2_ref(internal->priv_data.weakptr, delta, tag, file, line, func);
}
if (!(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)
{

@ -223,7 +223,29 @@ AST_TEST_DEFINE(astobj2_weak1)
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) {

Loading…
Cancel
Save