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;
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
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;
}
Exemplo n.º 5
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;
}
Exemplo n.º 6
0
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;
}
Exemplo n.º 7
0
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);
}