void __ao2_global_obj_release(struct ao2_global_obj *holder, const char *tag, const char *file, int line, const char *func, const char *name) { if (!holder) { /* For sanity */ ast_log(LOG_ERROR, "Must be called with a global object!\n"); ast_assert(0); return; } if (__ast_rwlock_wrlock(file, line, func, &holder->lock, name)) { /* Could not get the write lock. */ ast_assert(0); return; } /* Release the held ao2 object. */ if (holder->obj) { if (tag) { __ao2_ref_debug(holder->obj, -1, tag, file, line, func); } else { __ao2_ref(holder->obj, -1); } holder->obj = NULL; } __ast_rwlock_unlock(file, line, func, &holder->lock, name); }
void *__ao2_global_obj_ref(struct ao2_global_obj *holder, const char *tag, const char *file, int line, const char *func, const char *name) { void *obj; if (!holder) { /* For sanity */ ast_log(LOG_ERROR, "Must be called with a global object!\n"); ast_assert(0); return NULL; } if (__ast_rwlock_rdlock(file, line, func, &holder->lock, name)) { /* Could not get the read lock. */ ast_assert(0); return NULL; } obj = holder->obj; if (obj) { if (tag) { __ao2_ref_debug(obj, +1, tag, file, line, func); } else { __ao2_ref(obj, +1); } } __ast_rwlock_unlock(file, line, func, &holder->lock, name); return obj; }
int __ao2_unlock(void *user_data, const char *file, const char *func, int line, const char *var) { struct astobj2 *obj = INTERNAL_OBJ(user_data); struct astobj2_lock *obj_mutex; struct astobj2_rwlock *obj_rwlock; int res = 0; int current_value; if (obj == NULL) { ast_assert(0); return -1; } switch (obj->priv_data.options & AO2_ALLOC_OPT_LOCK_MASK) { case AO2_ALLOC_OPT_LOCK_MUTEX: obj_mutex = INTERNAL_OBJ_MUTEX(user_data); res = __ast_pthread_mutex_unlock(file, line, func, var, &obj_mutex->mutex.lock); #ifdef AO2_DEBUG if (!res) { ast_atomic_fetchadd_int(&ao2.total_locked, -1); } #endif break; case AO2_ALLOC_OPT_LOCK_RWLOCK: obj_rwlock = INTERNAL_OBJ_RWLOCK(user_data); current_value = ast_atomic_fetchadd_int(&obj_rwlock->rwlock.num_lockers, -1) - 1; if (current_value < 0) { /* It was a WRLOCK that we are unlocking. Fix the count. */ ast_atomic_fetchadd_int(&obj_rwlock->rwlock.num_lockers, -current_value); } res = __ast_rwlock_unlock(file, line, func, &obj_rwlock->rwlock.lock, var); #ifdef AO2_DEBUG if (!res) { ast_atomic_fetchadd_int(&ao2.total_locked, -1); } #endif break; case AO2_ALLOC_OPT_LOCK_NOLOCK: /* The ao2 object has no lock. */ break; default: ast_log(__LOG_ERROR, file, line, func, "Invalid lock option on ao2 object %p\n", user_data); res = -1; break; } return res; }
int __ast_heap_unlock(struct ast_heap *h, const char *file, const char *func, int line) { return __ast_rwlock_unlock(file, line, func, &h->lock, "&h->lock"); }