static void run_hashtest(int numthr) { pthread_t thr[numthr]; void *thrres[numthr]; int i; /* init a single global hashtab, then... */ glob_hashtab = ao2_container_alloc(180000, hash_string, hashtab_compare_strings); /* set a random seed */ glob_seed = (unsigned int)time(0); srand(glob_seed); /* create threads, each running hashtest */ for(i=0;i<numthr;i++) { unsigned long z = rand(); printf("starting hashtest thread %d....\n",i+1); if (ast_pthread_create(&thr[i], NULL, hashtest, (void*)z)) { printf("Sorry, couldn't create thread #%d\n", i+1); } printf("hashtest thread spawned.... \n"); } /* collect threads, each running hashtest */ for(i=0;i<numthr;i++) { printf("waiting for thread %d....\n", i+1); if (pthread_join(thr[i], &thrres[i])) { printf("Sorry, couldn't join thread #%d\n", i+1); } printf("hashtest thread %d done.... \n",i+1); } /* user has to kill/intr the process to stop the test? */ }
static int load_module(void) { CHECK_PJSIP_MODULE_LOADED(); if (ast_sip_register_subscription_handler(&mwi_handler)) { return AST_MODULE_LOAD_DECLINE; } unsolicited_mwi = ao2_container_alloc(MWI_BUCKETS, mwi_sub_hash, mwi_sub_cmp); if (!unsolicited_mwi) { ast_sip_unregister_subscription_handler(&mwi_handler); return AST_MODULE_LOAD_DECLINE; } create_mwi_subscriptions(); ast_sorcery_observer_add(ast_sip_get_sorcery(), "contact", &mwi_contact_observer); if (ast_test_flag(&ast_options, AST_OPT_FLAG_FULLY_BOOTED)) { ast_sip_push_task(NULL, send_initial_notify_all, NULL); } else { stasis_subscribe_pool(ast_manager_get_topic(), mwi_startup_event_cb, NULL); } return AST_MODULE_LOAD_SUCCESS; }
static void create_mwi_subscriptions(void) { struct ao2_container *mwi_subscriptions = ao2_container_alloc(MWI_BUCKETS, mwi_sub_hash, mwi_sub_cmp); RAII_VAR(struct ao2_container *, old_mwi_subscriptions, ao2_global_obj_ref(unsolicited_mwi), ao2_cleanup); RAII_VAR(struct ao2_container *, endpoints, ast_sorcery_retrieve_by_fields( ast_sip_get_sorcery(), "endpoint", AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL), ao2_cleanup); if (!mwi_subscriptions) { return; } /* We remove all the old stasis subscriptions first before applying the new configuration. This * prevents a situation where there might be multiple overlapping stasis subscriptions for an * endpoint for mailboxes. Though there may be mailbox changes during the gap between unsubscribing * and resubscribing, up-to-date mailbox state will be sent out to the endpoint when the * new stasis subscription is established */ if (old_mwi_subscriptions) { ao2_callback(old_mwi_subscriptions, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, unsubscribe, NULL); } ao2_callback(endpoints, OBJ_NODATA, create_mwi_subscriptions_for_endpoint, mwi_subscriptions); ao2_global_obj_replace_unref(unsolicited_mwi, mwi_subscriptions); ao2_ref(mwi_subscriptions, -1); }
static int load_module(void) { if (!(multiplexed_threads = ao2_container_alloc(MULTIPLEXED_BUCKETS, NULL, NULL))) { return AST_MODULE_LOAD_DECLINE; } return ast_bridge_technology_register(&multiplexed_bridge); }
static int ami_show_registrations(struct mansession *s, const struct message *m) { int count = 0; struct ast_sip_ami ami = { .s = s, .m = m, .arg = &count, .action_id = astman_get_header(m, "ActionID"), }; astman_send_listack(s, m, "Following are Events for each Inbound " "registration", "start"); ami_registrations_endpoints(&ami); astman_send_list_complete_start(s, m, "InboundRegistrationDetailComplete", count); astman_send_list_complete_end(s); return 0; } #define AMI_SHOW_REGISTRATIONS "PJSIPShowRegistrationsInbound" static pjsip_module registrar_module = { .name = { "Registrar", 9 }, .id = -1, .priority = PJSIP_MOD_PRIORITY_APPLICATION, .on_rx_request = registrar_on_rx_request, }; static int load_module(void) { const pj_str_t STR_REGISTER = { "REGISTER", 8 }; CHECK_PJSIP_MODULE_LOADED(); if (!(serializers = ao2_container_alloc( SERIALIZER_BUCKETS, serializer_hash, serializer_cmp))) { return AST_MODULE_LOAD_DECLINE; } if (ast_sip_register_service(®istrar_module)) { return AST_MODULE_LOAD_DECLINE; } if (pjsip_endpt_add_capability(ast_sip_get_pjsip_endpoint(), NULL, PJSIP_H_ALLOW, NULL, 1, &STR_REGISTER) != PJ_SUCCESS) { ast_sip_unregister_service(®istrar_module); return AST_MODULE_LOAD_DECLINE; } ast_manager_register_xml(AMI_SHOW_REGISTRATIONS, EVENT_FLAG_SYSTEM, ami_show_registrations); return AST_MODULE_LOAD_SUCCESS; } static int unload_module(void) { ast_manager_unregister(AMI_SHOW_REGISTRATIONS); ast_sip_unregister_service(®istrar_module); ao2_cleanup(serializers); return 0; }
/*! \brief Function called to load the module */ static int load_module(void) { if (!(cli_aliases = ao2_container_alloc(MAX_ALIAS_BUCKETS, alias_hash_cb, alias_cmp_cb))) { return AST_MODULE_LOAD_DECLINE; } load_config(0); ast_cli_register_multiple(cli_alias, ARRAY_LEN(cli_alias)); return AST_MODULE_LOAD_SUCCESS; }
int ast_cel_engine_init(void) { if (!(appset = ao2_container_alloc(NUM_APP_BUCKETS, app_hash, app_cmp))) { return -1; } if (!(linkedids = ao2_container_alloc(NUM_APP_BUCKETS, lid_hash, lid_cmp))) { ao2_ref(appset, -1); return -1; } if (do_reload() || ast_cli_register(&cli_status)) { ao2_ref(appset, -1); appset = NULL; ao2_ref(linkedids, -1); linkedids = NULL; return -1; } ast_register_atexit(ast_cel_engine_term); return 0; }
static int load_module(void) { if (!(multiplexed_threads = ao2_container_alloc(MULTIPLEXED_BUCKETS, NULL, NULL))) { return AST_MODULE_LOAD_DECLINE; } if (!(multiplexed_bridge.format_capabilities = ast_format_cap_alloc())) { return AST_MODULE_LOAD_DECLINE; } ast_format_cap_add_all_by_type(multiplexed_bridge.format_capabilities, AST_FORMAT_TYPE_AUDIO); ast_format_cap_add_all_by_type(multiplexed_bridge.format_capabilities, AST_FORMAT_TYPE_VIDEO); ast_format_cap_add_all_by_type(multiplexed_bridge.format_capabilities, AST_FORMAT_TYPE_TEXT); return ast_bridge_technology_register(&multiplexed_bridge); }
static int load_module(void) { if (!(kqueue_timers = ao2_container_alloc(563, kqueue_timer_hash, kqueue_timer_cmp))) { return AST_MODULE_LOAD_DECLINE; } if (!(timing_funcs_handle = ast_register_timing_interface(&kqueue_timing))) { ao2_ref(kqueue_timers, -1); return AST_MODULE_LOAD_DECLINE; } AST_TEST_REGISTER(test_kqueue_timing); return AST_MODULE_LOAD_SUCCESS; }
static struct ast_format_cap *cap_alloc_helper(int nolock) { struct ast_format_cap *cap = ast_calloc(1, sizeof(*cap)); if (!cap) { return NULL; } cap->nolock = nolock ? OBJ_NOLOCK : 0; if (!(cap->formats = ao2_container_alloc(283, hash_cb, cmp_cb))) { ast_free(cap); return NULL; } return cap; }
/* * \brief Allocate a threadpool * * This is implemented as a taskprocessor listener's alloc callback. This * is because the threadpool exists as the private data on a taskprocessor * listener. * * \param name The name of the threadpool. * \param options The options the threadpool uses. * \retval NULL Could not initialize threadpool properly * \retval non-NULL The newly-allocated threadpool */ static struct ast_threadpool *threadpool_alloc(const char *name, const struct ast_threadpool_options *options) { RAII_VAR(struct ast_threadpool *, pool, NULL, ao2_cleanup); struct ast_str *control_tps_name; pool = ao2_alloc(sizeof(*pool), threadpool_destructor); control_tps_name = ast_str_create(64); if (!pool || !control_tps_name) { ast_free(control_tps_name); return NULL; } ast_str_set(&control_tps_name, 0, "%s-control", name); pool->control_tps = ast_taskprocessor_get(ast_str_buffer(control_tps_name), TPS_REF_DEFAULT); ast_free(control_tps_name); if (!pool->control_tps) { return NULL; } pool->active_threads = ao2_container_alloc(THREAD_BUCKETS, worker_thread_hash, worker_thread_cmp); if (!pool->active_threads) { return NULL; } pool->idle_threads = ao2_container_alloc(THREAD_BUCKETS, worker_thread_hash, worker_thread_cmp); if (!pool->idle_threads) { return NULL; } pool->zombie_threads = ao2_container_alloc(THREAD_BUCKETS, worker_thread_hash, worker_thread_cmp); if (!pool->zombie_threads) { return NULL; } pool->options = *options; ao2_ref(pool, +1); return pool; }
int ast_ari_websocket_events_event_websocket_init(void) { /* Try to instantiate the registry */ event_session_registry = ao2_container_alloc(EVENT_SESSION_NUM_BUCKETS, event_session_hash, event_session_compare); if (!event_session_registry) { /* This is bad, bad. */ ast_log(LOG_WARNING, "Failed to allocate the local registry for websocket applications\n"); return -1; } return 0; }
static int load_module(void) { int r; r = STASIS_MESSAGE_TYPE_INIT(stasis_app_recording_snapshot_type); if (r != 0) { return AST_MODULE_LOAD_FAILURE; } recordings = ao2_container_alloc(RECORDING_BUCKETS, recording_hash, recording_cmp); if (!recordings) { return AST_MODULE_LOAD_FAILURE; } return AST_MODULE_LOAD_SUCCESS; }
static int load_module(void) { if (!(pthread_timers = ao2_container_alloc(PTHREAD_TIMER_BUCKETS, pthread_timer_hash, pthread_timer_cmp))) { return AST_MODULE_LOAD_DECLINE; } if (init_timing_thread()) { ao2_ref(pthread_timers, -1); pthread_timers = NULL; return AST_MODULE_LOAD_DECLINE; } return (timing_funcs_handle = ast_register_timing_interface(&pthread_timing)) ? AST_MODULE_LOAD_SUCCESS : AST_MODULE_LOAD_DECLINE; }
static struct mwi_subscription *mwi_subscription_alloc(struct ast_sip_endpoint *endpoint, unsigned int is_solicited, struct ast_sip_subscription *sip_sub) { struct mwi_subscription *sub; const char *endpoint_id = ast_sorcery_object_get_id(endpoint); sub = ao2_alloc(sizeof(*sub) + strlen(endpoint_id), mwi_subscription_destructor); if (!sub) { return NULL; } /* Safe strcpy */ strcpy(sub->id, endpoint_id); /* Unsolicited MWI doesn't actually result in a SIP subscription being * created. This is because a SIP subscription associates with a dialog. * Most devices expect unsolicited MWI NOTIFYs to appear out of dialog. If * they receive an in-dialog MWI NOTIFY (i.e. with a to-tag), then they * will reject the NOTIFY with a 481, thus resulting in message-waiting * state not being updated on the device */ if (is_solicited) { sub->sip_sub = ao2_bump(sip_sub); } sub->stasis_subs = ao2_container_alloc(STASIS_BUCKETS, stasis_sub_hash, stasis_sub_cmp); if (!sub->stasis_subs) { ao2_cleanup(sub); return NULL; } sub->is_solicited = is_solicited; if (!is_solicited && !ast_strlen_zero(endpoint->aors)) { sub->aors = ast_strdup(endpoint->aors); if (!sub->aors) { ao2_ref(sub, -1); return NULL; } } ast_debug(3, "Created %s MWI subscription for endpoint %s\n", is_solicited ? "solicited" : "unsolicited", sub->id); return sub; }
static struct ast_websocket_server *websocket_server_create_impl(void (*dtor)(void *)) { RAII_VAR(struct ast_websocket_server *, server, NULL, ao2_cleanup); server = ao2_alloc(sizeof(*server), dtor); if (!server) { return NULL; } server->protocols = ao2_container_alloc(MAX_PROTOCOL_BUCKETS, protocol_hash_fn, protocol_cmp_fn); if (!server->protocols) { return NULL; } ao2_ref(server, +1); return server; }
static int load_module(void) { const pj_str_t STR_REGISTER = { "REGISTER", 8 }; if (!(serializers = ao2_container_alloc( SERIALIZER_BUCKETS, serializer_hash, serializer_cmp))) { return AST_MODULE_LOAD_DECLINE; } if (ast_sip_register_service(®istrar_module)) { return AST_MODULE_LOAD_DECLINE; } if (pjsip_endpt_add_capability(ast_sip_get_pjsip_endpoint(), NULL, PJSIP_H_ALLOW, NULL, 1, &STR_REGISTER) != PJ_SUCCESS) { ast_sip_unregister_service(®istrar_module); return AST_MODULE_LOAD_DECLINE; } return AST_MODULE_LOAD_SUCCESS; }
struct stasis_topic_pool *stasis_topic_pool_create(struct stasis_topic *pooled_topic) { struct stasis_topic_pool *pool; pool = ao2_alloc_options(sizeof(*pool), topic_pool_dtor, AO2_ALLOC_OPT_LOCK_NOLOCK); if (!pool) { return NULL; } pool->pool_container = ao2_container_alloc(TOPIC_POOL_BUCKETS, topic_pool_entry_hash, topic_pool_entry_cmp); if (!pool->pool_container) { ao2_cleanup(pool); return NULL; } ao2_ref(pooled_topic, +1); pool->pool_topic = pooled_topic; return pool; }
struct stasis_cache *stasis_cache_create(snapshot_get_id id_fn) { RAII_VAR(struct stasis_cache *, cache, NULL, ao2_cleanup); cache = ao2_alloc_options(sizeof(*cache), cache_dtor, AO2_ALLOC_OPT_LOCK_NOLOCK); if (!cache) { return NULL; } cache->entries = ao2_container_alloc(NUM_CACHE_BUCKETS, cache_entry_hash, cache_entry_cmp); if (!cache->entries) { return NULL; } cache->id_fn = id_fn; ao2_ref(cache, +1); return cache; }
struct ast_multi_channel_blob *ast_multi_channel_blob_create(struct ast_json *blob) { RAII_VAR(struct ast_multi_channel_blob *, obj, ao2_alloc(sizeof(*obj), multi_channel_blob_dtor), ao2_cleanup); ast_assert(blob != NULL); if (!obj) { return NULL; } obj->channel_snapshots = ao2_container_alloc(NUM_MULTI_CHANNEL_BLOB_BUCKETS, channel_role_hash_cb, channel_role_single_cmp_cb); if (!obj->channel_snapshots) { return NULL; } obj->blob = ast_json_ref(blob); ao2_ref(obj, +1); return obj; }
static int load_module(void) { int fd; /* Make sure we support the necessary clock type */ if ((fd = timerfd_create(CLOCK_MONOTONIC, 0)) < 0) { ast_log(LOG_ERROR, "timerfd_create() not supported by the kernel. Not loading.\n"); return AST_MODULE_LOAD_DECLINE; } close(fd); if (!(timerfd_timers = ao2_container_alloc(TIMERFD_TIMER_BUCKETS, timerfd_timer_hash, timerfd_timer_cmp))) { return AST_MODULE_LOAD_DECLINE; } if (!(timing_funcs_handle = ast_register_timing_interface(&timerfd_timing))) { ao2_ref(timerfd_timers, -1); return AST_MODULE_LOAD_DECLINE; } return AST_MODULE_LOAD_SUCCESS; }
struct ast_channel *__ast_channel_internal_alloc(void (*destructor)(void *obj), const char *linkedid, const char *file, int line, const char *function) { struct ast_channel *tmp; #if defined(REF_DEBUG) tmp = __ao2_alloc_debug(sizeof(*tmp), destructor, AO2_ALLOC_OPT_LOCK_MUTEX, "", file, line, function, 1); #elif defined(__AST_DEBUG_MALLOC) tmp = __ao2_alloc_debug(sizeof(*tmp), destructor, AO2_ALLOC_OPT_LOCK_MUTEX, "", file, line, function, 0); #else tmp = ao2_alloc(sizeof(*tmp), destructor); #endif if ((ast_string_field_init(tmp, 128))) { return ast_channel_unref(tmp); } if (!(tmp->dialed_causes = ao2_container_alloc(DIALED_CAUSES_BUCKETS, pvt_cause_hash_fn, pvt_cause_cmp_fn))) { return ast_channel_unref(tmp); } if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) { ast_channel_uniqueid_build(tmp, "%li.%d", (long)time(NULL), ast_atomic_fetchadd_int(&uniqueint, 1)); } else { ast_channel_uniqueid_build(tmp, "%s-%li.%d", ast_config_AST_SYSTEM_NAME, (long)time(NULL), ast_atomic_fetchadd_int(&uniqueint, 1)); } if (!ast_strlen_zero(linkedid)) { ast_string_field_set(tmp, linkedid, linkedid); } else { ast_string_field_set(tmp, linkedid, tmp->uniqueid); } return tmp; }
struct ao2_container *ast_datastores_alloc(void) { return ao2_container_alloc(DATASTORE_BUCKETS, ast_datastore_hash_fn, ast_datastore_cmp_fn); }
static int astobj2_test_helper(int use_hash, int use_cmp, unsigned int lim, struct ast_test *test) { struct ao2_container *c1; struct ao2_container *c2; struct ao2_iterator it; struct test_obj *obj; struct test_obj tmp_obj; int bucket_size; int increment = 0; int destructor_count = 0; int num; int res = AST_TEST_PASS; /* This test needs at least 5 objects */ if (lim < 5) { lim = 5; } bucket_size = (ast_random() % ((lim / 4) + 1)) + 1; c1 = ao2_container_alloc(bucket_size, use_hash ? test_hash_cb : NULL, use_cmp ? test_cmp_cb : NULL); c2 = ao2_container_alloc(bucket_size, test_hash_cb, test_cmp_cb); if (!c1 || !c2) { ast_test_status_update(test, "ao2_container_alloc failed.\n"); res = AST_TEST_FAIL; goto cleanup; } /* Create objects and link into container */ destructor_count = lim; for (num = 1; num <= lim; num++) { if (!(obj = ao2_alloc(sizeof(struct test_obj), test_obj_destructor))) { ast_test_status_update(test, "ao2_alloc failed.\n"); res = AST_TEST_FAIL; goto cleanup; } snprintf(obj->c, sizeof(obj->c), "zombie #%d", num); obj->destructor_count = &destructor_count; obj->i = num; ao2_link(c1, obj); ao2_ref(obj, -1); if (ao2_container_count(c1) != num) { ast_test_status_update(test, "container did not link correctly\n"); res = AST_TEST_FAIL; } } ast_test_status_update(test, "Container created: random bucket size %d: number of items: %d\n", bucket_size, lim); /* Testing ao2_find with no flags */ num = 100; for (; num; num--) { int i = (ast_random() % ((lim / 2)) + 1); /* find a random object */ tmp_obj.i = i; if (!(obj = ao2_find(c1, &tmp_obj, 0))) { res = AST_TEST_FAIL; ast_test_status_update(test, "COULD NOT FIND:%d, ao2_find() with no flags failed.\n", i); } else { /* a correct match will only take place when the custom cmp function is used */ if (use_cmp && obj->i != i) { ast_test_status_update(test, "object %d does not match object %d\n", obj->i, tmp_obj.i); res = AST_TEST_FAIL; } ao2_ref(obj, -1); } } /* Testing ao2_find with OBJ_POINTER */ num = 75; for (; num; num--) { int i = (ast_random() % ((lim / 2)) + 1); /* find a random object */ snprintf(tmp_obj.c, sizeof(tmp_obj.c), "zombie #%d", i); tmp_obj.i = i; if (!(obj = ao2_find(c1, &tmp_obj, OBJ_POINTER))) { res = AST_TEST_FAIL; ast_test_status_update(test, "COULD NOT FIND:%d, ao2_find() with OBJ_POINTER flag failed.\n", i); } else { /* a correct match will only take place when the custom cmp function is used */ if (use_cmp && obj->i != i) { ast_test_status_update(test, "object %d does not match object %d\n", obj->i, tmp_obj.i); res = AST_TEST_FAIL; } ao2_ref(obj, -1); } } /* Testing ao2_find with OBJ_POINTER | OBJ_UNLINK | OBJ_CONTINUE. * In this test items are unlinked from c1 and placed in c2. Then * unlinked from c2 and placed back into c1. * * For this module and set of custom hash/cmp functions, an object * should only be found if the astobj2 default cmp function is used. * This test is designed to mimic the chan_iax.c call number use case. */ num = lim < 25 ? lim : 25; for (; num; num--) { if (!(obj = ao2_find(c1, NULL, OBJ_POINTER | OBJ_UNLINK | OBJ_CONTINUE))) { if (!use_cmp) { ast_test_status_update(test, "ao2_find with OBJ_POINTER | OBJ_UNLINK | OBJ_CONTINUE failed with default hash function.\n"); res = AST_TEST_FAIL; } } else { if (use_cmp) { ast_test_status_update(test, "ao2_find with OBJ_POINTER | OBJ_UNLINK | OBJ_CONTINUE failed with custom hash function.\n"); res = AST_TEST_FAIL; } ao2_link(c2, obj); ao2_ref(obj, -1); } } it = ao2_iterator_init(c2, 0); while ((obj = ao2_iterator_next(&it))) { ao2_unlink(c2, obj); ao2_link(c1, obj); ao2_ref(obj, -1); } ao2_iterator_destroy(&it); /* Test Callback with no flags. */ increment = 0; ao2_callback(c1, 0, increment_cb, &increment); if (increment != lim) { ast_test_status_update(test, "callback with no flags failed. Increment is %d\n", increment); res = AST_TEST_FAIL; } /* Test Callback with OBJ_NODATA. This should do nothing different than with no flags here. */ increment = 0; ao2_callback(c1, OBJ_NODATA, increment_cb, &increment); if (increment != lim) { ast_test_status_update(test, "callback with OBJ_NODATA failed. Increment is %d\n", increment); res = AST_TEST_FAIL; } /* Is the container count what we expect after all the finds and unlinks?*/ if (ao2_container_count(c1) != lim) { ast_test_status_update(test, "container count does not match what is expected after ao2_find tests.\n"); res = AST_TEST_FAIL; } /* Testing iterator. Unlink a single object and break. do not add item back */ it = ao2_iterator_init(c1, 0); num = (lim / 4) + 1; while ((obj = ao2_iterator_next(&it))) { if (obj->i == num) { ao2_ref(obj, -1); ao2_unlink(c1, obj); break; } ao2_ref(obj, -1); } ao2_iterator_destroy(&it); /* Is the container count what we expect after removing a single item? */ if (ao2_container_count(c1) != (lim - 1)) { ast_test_status_update(test, "unlink during iterator failed. Number %d was not removed.\n", num); res = AST_TEST_FAIL; } /* Test unlink all with OBJ_MULTIPLE, leave a single object for the container to destroy */ ao2_callback(c1, OBJ_MULTIPLE | OBJ_UNLINK | OBJ_NODATA, all_but_one_cb, NULL); /* check to make sure all test_obj destructors were called except for 1 */ if (destructor_count != 1) { ast_test_status_update(test, "OBJ_MULTIPLE | OBJ_UNLINK | OBJ_NODATA failed. destructor count %d\n", destructor_count); res = AST_TEST_FAIL; } cleanup: /* destroy containers */ if (c1) { ao2_ref(c1, -1); } if (c2) { ao2_ref(c2, -1); } if (destructor_count > 0) { ast_test_status_update(test, "all destructors were not called, destructor count is %d\n", destructor_count); res = AST_TEST_FAIL; } else if (destructor_count < 0) { ast_test_status_update(test, "Destructor was called too many times, destructor count is %d\n", destructor_count); res = AST_TEST_FAIL; } return res; }