예제 #1
0
static void *pthread_timer_open(void)
{
	struct pthread_timer *timer;

	if (!(timer = ao2_alloc(sizeof(*timer), pthread_timer_destructor))) {
		errno = ENOMEM;
		return NULL;
	}

	timer->pipe[PIPE_READ] = timer->pipe[PIPE_WRITE] = -1;
	timer->state = TIMER_STATE_IDLE;

	if (ast_pipe_nonblock(timer->pipe)) {
		ao2_ref(timer, -1);
		return NULL;
	}

	ao2_lock(pthread_timers);
	if (!ao2_container_count(pthread_timers)) {
		ast_mutex_lock(&timing_thread.lock);
		ast_cond_signal(&timing_thread.cond);
		ast_mutex_unlock(&timing_thread.lock);
	}
	ao2_link_flags(pthread_timers, timer, OBJ_NOLOCK);
	ao2_unlock(pthread_timers);

	return timer;
}
예제 #2
0
static int pthread_timer_open(void)
{
	struct pthread_timer *timer;
	int fd;

	if (!(timer = ao2_alloc(sizeof(*timer), pthread_timer_destructor))) {
		errno = ENOMEM;
		return -1;
	}

	timer->pipe[PIPE_READ] = timer->pipe[PIPE_WRITE] = -1;
	timer->state = TIMER_STATE_IDLE;

	if (pipe(timer->pipe)) {
		ao2_ref(timer, -1);
		return -1;
	}

	ao2_lock(pthread_timers);
	if (!ao2_container_count(pthread_timers)) {
		ast_mutex_lock(&timing_thread.lock);
		ast_cond_signal(&timing_thread.cond);
		ast_mutex_unlock(&timing_thread.lock);
	}
	ao2_link(pthread_timers, timer);
	ao2_unlock(pthread_timers);

	fd = timer->pipe[PIPE_READ];

	ao2_ref(timer, -1);

	return fd;
}
예제 #3
0
파일: res_ari.c 프로젝트: hardikk/asterisk
int ast_ari_remove_handler(struct stasis_rest_handlers *handler)
{
	RAII_VAR(struct stasis_rest_handlers *, new_handler, NULL, ao2_cleanup);
	size_t size, i, j;

	ast_assert(root_handler != NULL);

	ast_mutex_lock(&root_handler_lock);
	size = sizeof(*new_handler) +
		root_handler->num_children * sizeof(handler);

	new_handler = ao2_alloc(size, NULL);
	if (!new_handler) {
		return -1;
	}
	memcpy(new_handler, root_handler, sizeof(*new_handler));

	for (i = 0, j = 0; i < root_handler->num_children; ++i) {
		if (root_handler->children[i] == handler) {
			ast_module_unref(ast_module_info->self);
			continue;
		}
		new_handler->children[j++] = root_handler->children[i];
	}
	new_handler->num_children = j;

	ao2_cleanup(root_handler);
	ao2_ref(new_handler, +1);
	root_handler = new_handler;
	ast_mutex_unlock(&root_handler_lock);
	return 0;
}
예제 #4
0
static void parse_apps(const char *val)
{
	char *apps = ast_strdupa(val);
	char *cur_app;

	if (!ast_cel_track_event(AST_CEL_APP_START) && !ast_cel_track_event(AST_CEL_APP_END)) {
		ast_log(LOG_WARNING, "An apps= config line, but not tracking APP events\n");
		return;
	}

	while ((cur_app = strsep(&apps, ","))) {
		char *app;

		cur_app = ast_strip(cur_app);
		if (ast_strlen_zero(cur_app)) {
			continue;
		}

		if (!(app = ao2_alloc(strlen(cur_app) + 1, NULL))) {
			continue;
		}
		strcpy(app, cur_app);

		ao2_link(appset, app);
		ao2_ref(app, -1);
		app = NULL;
	}
}
예제 #5
0
struct stasis_app_control *control_create(struct ast_channel *channel, struct stasis_app *app)
{
	RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
	int res;

	control = ao2_alloc(sizeof(*control), control_dtor);
	if (!control) {
		return NULL;
	}

	control->app = ao2_bump(app);

	res = ast_cond_init(&control->wait_cond, NULL);
	if (res != 0) {
		ast_log(LOG_ERROR, "Error initializing ast_cond_t: %s\n",
			strerror(errno));
		return NULL;
	}

	control->command_queue = ao2_container_alloc_list(
		AO2_ALLOC_OPT_LOCK_MUTEX, 0, NULL, NULL);

	if (!control->command_queue) {
		return NULL;
	}

	control->channel = channel;

	AST_LIST_HEAD_INIT(&control->add_rules);
	AST_LIST_HEAD_INIT(&control->remove_rules);

	ao2_ref(control, +1);
	return control;
}
예제 #6
0
void ast_sip_dialog_set_serializer(pjsip_dialog *dlg, struct ast_taskprocessor *serializer)
{
	struct distributor_dialog_data *dist;

	ao2_wrlock(dialog_associations);
	dist = ao2_find(dialog_associations, dlg, OBJ_SEARCH_KEY | OBJ_NOLOCK);
	if (!dist) {
		if (serializer) {
			dist = ao2_alloc(sizeof(*dist), NULL);
			if (dist) {
				dist->dlg = dlg;
				dist->serializer = serializer;
				ao2_link_flags(dialog_associations, dist, OBJ_NOLOCK);
				ao2_ref(dist, -1);
			}
		}
	} else {
		ao2_lock(dist);
		dist->serializer = serializer;
		if (!dist->serializer && !dist->endpoint) {
			ao2_unlink_flags(dialog_associations, dist, OBJ_NOLOCK);
		}
		ao2_unlock(dist);
		ao2_ref(dist, -1);
	}
	ao2_unlock(dialog_associations);
}
예제 #7
0
파일: tcptls.c 프로젝트: mtulio/mtulio
struct ast_tcptls_session_instance *ast_tcptls_client_create(struct ast_tcptls_session_args *desc)
{
	int x = 1;
	struct ast_tcptls_session_instance *tcptls_session = NULL;

	/* Do nothing if nothing has changed */
	if (!ast_sockaddr_cmp(&desc->old_address, &desc->remote_address)) {
		ast_debug(1, "Nothing changed in %s\n", desc->name);
		return NULL;
	}

	/* If we return early, there is no connection */
	ast_sockaddr_setnull(&desc->old_address);

	if (desc->accept_fd != -1)
		close(desc->accept_fd);

	desc->accept_fd = socket(ast_sockaddr_is_ipv6(&desc->remote_address) ?
				 AF_INET6 : AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (desc->accept_fd < 0) {
		ast_log(LOG_WARNING, "Unable to allocate socket for %s: %s\n",
			desc->name, strerror(errno));
		return NULL;
	}

	/* if a local address was specified, bind to it so the connection will
	   originate from the desired address */
	if (!ast_sockaddr_isnull(&desc->local_address)) {
		setsockopt(desc->accept_fd, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x));
		if (ast_bind(desc->accept_fd, &desc->local_address)) {
			ast_log(LOG_ERROR, "Unable to bind %s to %s: %s\n",
				desc->name,
				ast_sockaddr_stringify(&desc->local_address),
				strerror(errno));
			goto error;
		}
	}

	if (!(tcptls_session = ao2_alloc(sizeof(*tcptls_session), session_instance_destructor)))
		goto error;

	ast_mutex_init(&tcptls_session->lock);
	tcptls_session->client = 1;
	tcptls_session->fd = desc->accept_fd;
	tcptls_session->parent = desc;
	tcptls_session->parent->worker_fn = NULL;
	ast_sockaddr_copy(&tcptls_session->remote_address,
			  &desc->remote_address);

	/* Set current info */
	ast_sockaddr_copy(&desc->old_address, &desc->remote_address);
	return tcptls_session;

error:
	close(desc->accept_fd);
	desc->accept_fd = -1;
	if (tcptls_session)
		ao2_ref(tcptls_session, -1);
	return NULL;
}
예제 #8
0
struct ast_dns_query_recurring *ast_dns_resolve_recurring(const char *name, int rr_type, int rr_class, ast_dns_resolve_callback callback, void *data)
{
	struct ast_dns_query_recurring *recurring;

	if (ast_strlen_zero(name) || !callback || !ast_dns_get_sched()) {
		return NULL;
	}

	recurring = ao2_alloc(sizeof(*recurring) + strlen(name) + 1, dns_query_recurring_destroy);
	if (!recurring) {
		return NULL;
	}

	recurring->callback = callback;
	recurring->user_data = ao2_bump(data);
	recurring->timer = -1;
	recurring->rr_type = rr_type;
	recurring->rr_class = rr_class;
	strcpy(recurring->name, name); /* SAFE */

	recurring->active = ast_dns_resolve_async(name, rr_type, rr_class, dns_query_recurring_resolution_callback, recurring);
	if (!recurring->active) {
		ao2_ref(recurring, -1);
		return NULL;
	}

	return recurring;
}
예제 #9
0
파일: tcptls.c 프로젝트: litnimax/asterisk
void *ast_tcptls_server_root(void *data)
{
    struct ast_tcptls_session_args *desc = data;
    int fd;
    struct ast_sockaddr addr;
    struct ast_tcptls_session_instance *tcptls_session;
    pthread_t launched;

    for (;;) {
        int i, flags;

        if (desc->periodic_fn) {
            desc->periodic_fn(desc);
        }
        i = ast_wait_for_input(desc->accept_fd, desc->poll_timeout);
        if (i <= 0) {
            continue;
        }
        fd = ast_accept(desc->accept_fd, &addr);
        if (fd < 0) {
            if ((errno != EAGAIN) && (errno != EWOULDBLOCK) && (errno != EINTR) && (errno != ECONNABORTED)) {
                ast_log(LOG_ERROR, "Accept failed: %s\n", strerror(errno));
                break;
            }
            continue;
        }
        tcptls_session = ao2_alloc(sizeof(*tcptls_session), session_instance_destructor);
        if (!tcptls_session) {
            ast_log(LOG_WARNING, "No memory for new session: %s\n", strerror(errno));
            if (close(fd)) {
                ast_log(LOG_ERROR, "close() failed: %s\n", strerror(errno));
            }
            continue;
        }

        tcptls_session->overflow_buf = ast_str_create(128);
        flags = fcntl(fd, F_GETFL);
        fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);

        tcptls_session->stream = ast_iostream_from_fd(&fd);
        if (!tcptls_session->stream) {
            ast_log(LOG_WARNING, "No memory for new session iostream\n");
            continue;
        }

        tcptls_session->parent = desc;
        ast_sockaddr_copy(&tcptls_session->remote_address, &addr);

        tcptls_session->client = 0;

        /* This thread is now the only place that controls the single ref to tcptls_session */
        if (ast_pthread_create_detached_background(&launched, NULL, handle_tcptls_connection, tcptls_session)) {
            ast_log(LOG_ERROR, "Unable to launch helper thread: %s\n", strerror(errno));
            ast_tcptls_close_session_file(tcptls_session);
            ao2_ref(tcptls_session, -1);
        }
    }
    return NULL;
}
예제 #10
0
struct ast_tcptls_session_instance *ast_tcptls_client_create(struct ast_tcptls_session_args *desc)
{
	int x = 1;
	struct ast_tcptls_session_instance *tcptls_session = NULL;

	/* Do nothing if nothing has changed */
	if (!memcmp(&desc->old_address, &desc->remote_address, sizeof(desc->old_address))) {
		ast_debug(1, "Nothing changed in %s\n", desc->name);
		return NULL;
	}

	desc->old_address = desc->remote_address;

	if (desc->accept_fd != -1)
		close(desc->accept_fd);

	desc->accept_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (desc->accept_fd < 0) {
		ast_log(LOG_WARNING, "Unable to allocate socket for %s: %s\n",
			desc->name, strerror(errno));
		return NULL;
	}

	/* if a local address was specified, bind to it so the connection will
	   originate from the desired address */
	if (desc->local_address.sin_family != 0) {
		setsockopt(desc->accept_fd, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x));
		if (bind(desc->accept_fd, (struct sockaddr *) &desc->local_address, sizeof(desc->local_address))) {
			ast_log(LOG_ERROR, "Unable to bind %s to %s:%d: %s\n",
			desc->name,
				ast_inet_ntoa(desc->local_address.sin_addr), ntohs(desc->local_address.sin_port),
				strerror(errno));
			goto error;
		}
	}

	if (!(tcptls_session = ao2_alloc(sizeof(*tcptls_session), session_instance_destructor)))
		goto error;

	ast_mutex_init(&tcptls_session->lock);
	tcptls_session->client = 1;
	tcptls_session->fd = desc->accept_fd;
	tcptls_session->parent = desc;
	tcptls_session->parent->worker_fn = NULL;
	memcpy(&tcptls_session->remote_address, &desc->remote_address, sizeof(tcptls_session->remote_address));

	return tcptls_session;

error:
	close(desc->accept_fd);
	desc->accept_fd = -1;
	if (tcptls_session)
		ao2_ref(tcptls_session, -1);
	return NULL;
}
예제 #11
0
파일: threadpool.c 프로젝트: GGGO/asterisk
struct ast_threadpool_listener *ast_threadpool_listener_alloc(
		const struct ast_threadpool_listener_callbacks *callbacks, void *user_data)
{
	struct ast_threadpool_listener *listener = ao2_alloc(sizeof(*listener), NULL);
	if (!listener) {
		return NULL;
	}
	listener->callbacks = callbacks;
	listener->user_data = user_data;
	return listener;
}
예제 #12
0
파일: threadpool.c 프로젝트: GGGO/asterisk
struct ast_serializer_shutdown_group *ast_serializer_shutdown_group_alloc(void)
{
	struct ast_serializer_shutdown_group *shutdown_group;

	shutdown_group = ao2_alloc(sizeof(*shutdown_group), serializer_shutdown_group_dtor);
	if (!shutdown_group) {
		return NULL;
	}
	ast_cond_init(&shutdown_group->cond, NULL);
	return shutdown_group;
}
예제 #13
0
static struct app_data *app_data_create(void)
{
	struct app_data *res = ao2_alloc(sizeof(struct app_data), app_data_dtor);

	if (!res) {
		return NULL;
	}

	res->messages = ast_json_array_create();
	return res;
}
예제 #14
0
파일: threadpool.c 프로젝트: GGGO/asterisk
/*!
 * \brief Allocate and initialize a task_pushed_data
 * \param pool The threadpool to set in the task_pushed_data
 * \param was_empty The was_empty value to set in the task_pushed_data
 * \retval NULL Unable to allocate task_pushed_data
 * \retval non-NULL The newly-allocated task_pushed_data
 */
static struct task_pushed_data *task_pushed_data_alloc(struct ast_threadpool *pool,
		int was_empty)
{
	struct task_pushed_data *tpd = ao2_alloc(sizeof(*tpd), NULL);

	if (!tpd) {
		return NULL;
	}
	tpd->pool = pool;
	tpd->was_empty = was_empty;
	return tpd;
}
예제 #15
0
파일: threadpool.c 프로젝트: GGGO/asterisk
/*!
 * \brief Allocate and initialize a thread_worker_pair
 * \param pool Threadpool to assign to the thread_worker_pair
 * \param worker Worker thread to assign to the thread_worker_pair
 */
static struct thread_worker_pair *thread_worker_pair_alloc(struct ast_threadpool *pool,
		struct worker_thread *worker)
{
	struct thread_worker_pair *pair = ao2_alloc(sizeof(*pair), thread_worker_pair_destructor);
	if (!pair) {
		return NULL;
	}
	pair->pool = pool;
	ao2_ref(worker, +1);
	pair->worker = worker;
	return pair;
}
예제 #16
0
파일: threadpool.c 프로젝트: GGGO/asterisk
/*!
 * \brief Allocate and initialize a set_size_data
 * \param pool The pool for the set_size_data
 * \param size The size to store in the set_size_data
 */
static struct set_size_data *set_size_data_alloc(struct ast_threadpool *pool,
		unsigned int size)
{
	struct set_size_data *ssd = ao2_alloc(sizeof(*ssd), NULL);
	if (!ssd) {
		return NULL;
	}

	ssd->pool = pool;
	ssd->size = size;
	return ssd;
}
예제 #17
0
struct ast_json_payload *ast_json_payload_create(struct ast_json *json)
{
	struct ast_json_payload *payload;

	if (!(payload = ao2_alloc(sizeof(*payload), json_payload_destructor))) {
		return NULL;
	}

	ast_json_ref(json);
	payload->json = json;

	return payload;
}
예제 #18
0
/*! /brief Create test element */
static char *ht_new(int i)
{
    const int buflen = 12;
    char *keybuf = ao2_alloc(buflen, ht_delete);
    int needed;
    if (keybuf == NULL) {
        return NULL;
    }
    needed = snprintf(keybuf, buflen, "key%08x", i);
    ast_atomic_fetchadd_int(&alloc_count, 1);
    ast_assert(needed + 1 <= buflen);
    return keybuf;
}
예제 #19
0
파일: res_ari.c 프로젝트: popsodav/asterisk
static struct stasis_rest_handlers *root_handler_create(void)
{
    RAII_VAR(struct stasis_rest_handlers *, handler, NULL, ao2_cleanup);

    handler = ao2_alloc(sizeof(*handler), NULL);
    if (!handler) {
        return NULL;
    }
    handler->path_segment = "ari";

    ao2_ref(handler, +1);
    return handler;
}
예제 #20
0
static struct consumer *consumer_create(void)
{
    struct consumer *consumer;

    consumer = ao2_alloc(sizeof(*consumer), consumer_dtor);
    if (!consumer) {
        return NULL;
    }

    ast_cond_init(&consumer->out, NULL);
    consumer_reset(consumer);

    return consumer;
}
예제 #21
0
static struct recurring_data *recurring_data_alloc(void)
{
	struct recurring_data *rdata;

	rdata = ao2_alloc(sizeof(*rdata), recurring_data_destructor);
	if (!rdata) {
		return NULL;
	}

	ast_mutex_init(&rdata->lock);
	ast_cond_init(&rdata->cond, NULL);

	return rdata;
}
예제 #22
0
void *ast_tcptls_server_root(void *data)
{
	struct ast_tcptls_session_args *desc = data;
	int fd;
	struct sockaddr_in sin;
	socklen_t sinlen;
	struct ast_tcptls_session_instance *tcptls_session;
	pthread_t launched;
	
	for (;;) {
		int i, flags;

		if (desc->periodic_fn)
			desc->periodic_fn(desc);
		i = ast_wait_for_input(desc->accept_fd, desc->poll_timeout);
		if (i <= 0)
			continue;
		sinlen = sizeof(sin);
		fd = accept(desc->accept_fd, (struct sockaddr *) &sin, &sinlen);
		if (fd < 0) {
			if ((errno != EAGAIN) && (errno != EINTR))
				ast_log(LOG_WARNING, "Accept failed: %s\n", strerror(errno));
			continue;
		}
		tcptls_session = ao2_alloc(sizeof(*tcptls_session), session_instance_destructor);
		if (!tcptls_session) {
			ast_log(LOG_WARNING, "No memory for new session: %s\n", strerror(errno));
			close(fd);
			continue;
		}

		ast_mutex_init(&tcptls_session->lock);

		flags = fcntl(fd, F_GETFL);
		fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
		tcptls_session->fd = fd;
		tcptls_session->parent = desc;
		memcpy(&tcptls_session->remote_address, &sin, sizeof(tcptls_session->remote_address));

		tcptls_session->client = 0;
			
		/* This thread is now the only place that controls the single ref to tcptls_session */
		if (ast_pthread_create_detached_background(&launched, NULL, handle_tcptls_connection, tcptls_session)) {
			ast_log(LOG_WARNING, "Unable to launch helper thread: %s\n", strerror(errno));
			close(tcptls_session->fd);
			ao2_ref(tcptls_session, -1);
		}
	}
	return NULL;
}
예제 #23
0
파일: hashtest2.c 프로젝트: mtulio/mtulio
static void add_element(void)
{
	char keybuf[100];
	struct ht_element *x = ao2_alloc(sizeof(struct ht_element), ht_destroy);
	sprintf(keybuf,"key%08d", glob_highwater++);
	x->key = strdup(keybuf);
	x->val = strdup("interesting data");
#ifdef DEBUG
	printf("+ %s\n", keybuf);
#endif	
	ao2_link(glob_hashtab, x);
	
	els_added++; /* unprotected, sometimes off, but, not really important, either */
}
예제 #24
0
/*! \brief Initialize sorcery with auth support */
int ast_sip_initialize_sorcery_auth(void)
{
	struct ast_sorcery *sorcery = ast_sip_get_sorcery();

	ast_sorcery_apply_default(sorcery, SIP_SORCERY_AUTH_TYPE, "config", "pjsip.conf,criteria=type=auth");

	if (ast_sorcery_object_register(sorcery, SIP_SORCERY_AUTH_TYPE, auth_alloc, NULL, auth_apply)) {
		return -1;
	}

	ast_sorcery_object_field_register(sorcery, SIP_SORCERY_AUTH_TYPE, "type", "",
			OPT_NOOP_T, 0, 0);
	ast_sorcery_object_field_register(sorcery, SIP_SORCERY_AUTH_TYPE, "username",
			"", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_auth, auth_user));
	ast_sorcery_object_field_register(sorcery, SIP_SORCERY_AUTH_TYPE, "password",
			"", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_auth, auth_pass));
	ast_sorcery_object_field_register(sorcery, SIP_SORCERY_AUTH_TYPE, "md5_cred",
			"", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_auth, md5_creds));
	ast_sorcery_object_field_register(sorcery, SIP_SORCERY_AUTH_TYPE, "realm",
			"", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_auth, realm));
	ast_sorcery_object_field_register(sorcery, SIP_SORCERY_AUTH_TYPE, "nonce_lifetime",
			"32", OPT_UINT_T, 0, FLDSET(struct ast_sip_auth, nonce_lifetime));
	ast_sorcery_object_field_register_custom(sorcery, SIP_SORCERY_AUTH_TYPE, "auth_type",
			"userpass", auth_type_handler, auth_type_to_str, NULL, 0, 0);

	ast_sip_register_endpoint_formatter(&endpoint_auth_formatter);

	cli_formatter = ao2_alloc(sizeof(struct ast_sip_cli_formatter_entry), NULL);
	if (!cli_formatter) {
		ast_log(LOG_ERROR, "Unable to allocate memory for cli formatter\n");
		return -1;
	}
	cli_formatter->name = SIP_SORCERY_AUTH_TYPE;
	cli_formatter->print_header = cli_print_header;
	cli_formatter->print_body = cli_print_body;
	cli_formatter->get_container = cli_get_container;
	cli_formatter->iterate = cli_iterator;
	cli_formatter->get_id = ast_sorcery_object_get_id;
	cli_formatter->retrieve_by_id = cli_retrieve_by_id;

	ast_sip_register_cli_formatter(cli_formatter);
	ast_cli_register_multiple(cli_commands, ARRAY_LEN(cli_commands));

	if (ast_manager_register_xml("PJSIPShowAuths", EVENT_FLAG_SYSTEM, ami_show_auths)) {
		return -1;
	}

	return 0;
}
예제 #25
0
int ast_channel_dialed_causes_add(const struct ast_channel *chan, const struct ast_control_pvt_cause_code *cause_code, int datalen)
{
	struct ast_control_pvt_cause_code *ao2_cause_code;
	ao2_find(chan->dialed_causes, cause_code->chan_name, OBJ_KEY | OBJ_UNLINK | OBJ_NODATA);
	ao2_cause_code = ao2_alloc(datalen, NULL);

	if (ao2_cause_code) {
		memcpy(ao2_cause_code, cause_code, datalen);
		ao2_link(chan->dialed_causes, ao2_cause_code);
		ao2_ref(ao2_cause_code, -1);
		return 0;
	} else {
		return -1;
	}
}
예제 #26
0
파일: threadpool.c 프로젝트: GGGO/asterisk
/*!
 * \brief Allocate and initialize a new worker thread
 *
 * This will create, initialize, and start the thread.
 *
 * \param pool The threadpool to which the worker will be added
 * \retval NULL Failed to allocate or start the worker thread
 * \retval non-NULL The newly-created worker thread
 */
static struct worker_thread *worker_thread_alloc(struct ast_threadpool *pool)
{
	struct worker_thread *worker = ao2_alloc(sizeof(*worker), worker_thread_destroy);
	if (!worker) {
		return NULL;
	}
	worker->id = ast_atomic_fetchadd_int(&worker_id_counter, 1);
	ast_mutex_init(&worker->lock);
	ast_cond_init(&worker->cond, NULL);
	worker->pool = pool;
	worker->thread = AST_PTHREADT_NULL;
	worker->state = ALIVE;
	worker->options = pool->options;
	return worker;
}
예제 #27
0
/*! \brief Allocator for T.38 data */
static struct t38_parameters_task_data *t38_parameters_task_data_alloc(struct ast_sip_session *session,
	struct ast_frame *frame)
{
	struct t38_parameters_task_data *data = ao2_alloc(sizeof(*data), t38_parameters_task_data_destroy);

	if (!data) {
		return NULL;
	}

	data->session = session;
	ao2_ref(session, +1);
	data->frame = frame;

	return data;
}
예제 #28
0
/*! \brief Create a task_data object */
static struct task_data *task_data_create(void)
{
	struct task_data *task_data =
		ao2_alloc(sizeof(*task_data), task_data_dtor);

	if (!task_data) {
		return NULL;
	}

	ast_cond_init(&task_data->cond, NULL);
	ast_mutex_init(&task_data->lock);
	task_data->task_complete = 0;
	task_data->wait_time = 0;

	return task_data;
}
예제 #29
0
static struct shutdown_data *shutdown_data_create(int dont_wait)
{
	RAII_VAR(struct shutdown_data *, shutdown_data, NULL, ao2_cleanup);

	shutdown_data = ao2_alloc(sizeof(*shutdown_data), shutdown_data_dtor);
	if (!shutdown_data) {
		return NULL;
	}

	ast_mutex_init(&shutdown_data->lock);
	ast_cond_init(&shutdown_data->in, NULL);
	ast_cond_init(&shutdown_data->out, NULL);
	shutdown_data->task_stop_waiting = dont_wait;
	ao2_ref(shutdown_data, +1);
	return shutdown_data;
}
static void *timerfd_timer_open(void)
{
	struct timerfd_timer *timer;

	if (!(timer = ao2_alloc(sizeof(*timer), timer_destroy))) {
		ast_log(LOG_ERROR, "Could not allocate memory for timerfd_timer structure\n");
		return NULL;
	}
	if ((timer->fd = timerfd_create(CLOCK_MONOTONIC, 0)) < 0) {
		ast_log(LOG_ERROR, "Failed to create timerfd timer: %s\n", strerror(errno));
		ao2_ref(timer, -1);
		return NULL;
	}

	return timer;
}