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; }
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; }
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; }
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; } }
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; }
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); }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
/*! * \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; }
/*! * \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; }
/*! * \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; }
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; }
/*! /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; }
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; }
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; }
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; }
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; }
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 */ }
/*! \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; }
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; } }
/*! * \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; }
/*! \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; }
/*! \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; }
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; }