static int load_module(void) { CHECK_PJSIP_MODULE_LOADED(); contact_autoexpire = ao2_container_alloc_options(AO2_ALLOC_OPT_LOCK_NOLOCK, CONTACT_AUTOEXPIRE_BUCKETS, contact_expiration_hash, contact_expiration_cmp); if (!contact_autoexpire) { ast_log(LOG_ERROR, "Could not create container for contact auto-expiration\n"); return AST_MODULE_LOAD_FAILURE; } if (!(sched = ast_sched_context_create())) { ast_log(LOG_ERROR, "Could not create scheduler for contact auto-expiration\n"); unload_module(); return AST_MODULE_LOAD_FAILURE; } if (ast_sched_start_thread(sched)) { ast_log(LOG_ERROR, "Could not start scheduler thread for contact auto-expiration\n"); unload_module(); return AST_MODULE_LOAD_FAILURE; } contact_expiration_initialize_existing(); if (ast_sorcery_observer_add(ast_sip_get_sorcery(), "contact", &contact_expiration_observer)) { ast_log(LOG_ERROR, "Could not add observer for notifications about contacts for contact auto-expiration\n"); unload_module(); return AST_MODULE_LOAD_FAILURE; } return AST_MODULE_LOAD_SUCCESS; }
struct ast_channel *ast_pickup_find_by_group(struct ast_channel *chan) { struct ao2_container *candidates;/*!< Candidate channels found to pickup. */ struct ast_channel *target;/*!< Potential pickup target */ candidates = ao2_container_alloc_options(AO2_ALLOC_OPT_LOCK_NOLOCK, 1, NULL, NULL); if (!candidates) { return NULL; } /* Find all candidate targets by group. */ ast_channel_callback(find_channel_by_group, chan, candidates, 0); /* Find the oldest pickup target candidate */ target = NULL; for (;;) { struct ast_channel *candidate;/*!< Potential new older target */ struct ao2_iterator iter; iter = ao2_iterator_init(candidates, 0); while ((candidate = ao2_iterator_next(&iter))) { if (!target) { /* First target. */ target = candidate; continue; } if (ast_tvcmp(ast_channel_creationtime(candidate), ast_channel_creationtime(target)) < 0) { /* We have a new target. */ ast_channel_unref(target); target = candidate; continue; } ast_channel_unref(candidate); } ao2_iterator_destroy(&iter); if (!target) { /* No candidates found. */ break; } /* The found channel must be locked and ref'd. */ ast_channel_lock(target); /* Recheck pickup ability */ if (ast_can_pickup(target)) { /* This is the channel to pickup. */ break; } /* Someone else picked it up or the call went away. */ ast_channel_unlock(target); ao2_unlink(candidates, target); target = ast_channel_unref(target); } ao2_ref(candidates, -1); return target; }
int ast_format_cache_init(void) { formats = ao2_container_alloc_options(AO2_ALLOC_OPT_LOCK_RWLOCK, CACHE_BUCKETS, format_hash_cb, format_cmp_cb); if (!formats) { return -1; } ast_register_cleanup(format_cache_shutdown); return 0; }
int ast_codec_init(void) { codecs = ao2_container_alloc_options(AO2_ALLOC_OPT_LOCK_RWLOCK, CODEC_BUCKETS, codec_hash, codec_cmp); if (!codecs) { return -1; } ast_cli_register_multiple(codec_cli, ARRAY_LEN(codec_cli)); ast_register_cleanup(codec_shutdown); return 0; }
struct ao2_container *stasis_cache_dump(struct stasis_cache *cache, struct stasis_message_type *type) { struct cache_dump_data cache_dump; ast_assert(cache->entries != NULL); cache_dump.type = type; cache_dump.cached = ao2_container_alloc_options( AO2_ALLOC_OPT_LOCK_NOLOCK, 1, NULL, NULL); if (!cache_dump.cached) { return NULL; } ao2_callback(cache->entries, OBJ_MULTIPLE | OBJ_NODATA, cache_dump_cb, &cache_dump); return cache_dump.cached; }
static void *notify_cfg_alloc(void) { struct notify_cfg *cfg; if (!(cfg = ao2_alloc(sizeof(*cfg), notify_cfg_destroy))) { return NULL; } if (!(cfg->notify_options = ao2_container_alloc_options( AO2_ALLOC_OPT_LOCK_NOLOCK, 20, notify_option_hash, notify_option_cmp))) { ao2_cleanup(cfg); return NULL; } return cfg; }
struct ao2_container *ast_str_container_alloc_options(enum ao2_container_opts opts, int buckets) { return ao2_container_alloc_options(opts, buckets, str_hash, str_cmp); }