struct ast_heap *ast_heap_destroy(struct ast_heap *h) { ast_free(h->heap); h->heap = NULL; ast_rwlock_destroy(&h->lock); ast_free(h); return NULL; }
static void interface_destroy_cb(void *obj) { struct interface_ao2_wrapper *wrapper = obj; ast_rwlock_destroy(&wrapper->wraplock); }
static int internal_ao2_ref(void *user_data, int delta, const char *file, int line, const char *func) { struct astobj2 *obj = INTERNAL_OBJ(user_data); struct astobj2_lock *obj_mutex; struct astobj2_rwlock *obj_rwlock; int current_value; int ret; if (obj == NULL) { ast_assert(0); return -1; } /* if delta is 0, just return the refcount */ if (delta == 0) { return obj->priv_data.ref_counter; } /* we modify with an atomic operation the reference counter */ ret = ast_atomic_fetchadd_int(&obj->priv_data.ref_counter, delta); current_value = ret + delta; #ifdef AO2_DEBUG ast_atomic_fetchadd_int(&ao2.total_refs, delta); #endif if (0 < current_value) { /* The object still lives. */ return ret; } /* this case must never happen */ if (current_value < 0) { ast_log(__LOG_ERROR, file, line, func, "Invalid refcount %d on ao2 object %p\n", current_value, user_data); ast_assert(0); /* stop here even if assert doesn't DO_CRASH */ return -1; } /* last reference, destroy the object */ if (obj->priv_data.destructor_fn != NULL) { obj->priv_data.destructor_fn(user_data); } #ifdef AO2_DEBUG ast_atomic_fetchadd_int(&ao2.total_mem, - obj->priv_data.data_size); ast_atomic_fetchadd_int(&ao2.total_objects, -1); #endif /* In case someone uses an object after it's been freed */ obj->priv_data.magic = 0; switch (obj->priv_data.options & AO2_ALLOC_OPT_LOCK_MASK) { case AO2_ALLOC_OPT_LOCK_MUTEX: obj_mutex = INTERNAL_OBJ_MUTEX(user_data); ast_mutex_destroy(&obj_mutex->mutex.lock); ast_free(obj_mutex); break; case AO2_ALLOC_OPT_LOCK_RWLOCK: obj_rwlock = INTERNAL_OBJ_RWLOCK(user_data); ast_rwlock_destroy(&obj_rwlock->rwlock.lock); ast_free(obj_rwlock); break; case AO2_ALLOC_OPT_LOCK_NOLOCK: ast_free(obj); break; default: ast_log(__LOG_ERROR, file, line, func, "Invalid lock option on ao2 object %p\n", user_data); break; } return ret; }