pa_mempool* pa_mempool_new(int shared) { pa_mempool *p; p = pa_xnew(pa_mempool, 1); p->mutex = pa_mutex_new(TRUE, TRUE); p->semaphore = pa_semaphore_new(0); p->block_size = PA_PAGE_ALIGN(PA_MEMPOOL_SLOT_SIZE); if (p->block_size < PA_PAGE_SIZE) p->block_size = PA_PAGE_SIZE; p->n_blocks = PA_MEMPOOL_SLOTS_MAX; pa_assert(p->block_size > PA_ALIGN(sizeof(struct mempool_slot))); if (pa_shm_create_rw(&p->memory, p->n_blocks * p->block_size, shared, 0700) < 0) { pa_xfree(p); return NULL; } memset(&p->stat, 0, sizeof(p->stat)); pa_atomic_store(&p->n_init, 0); PA_LLIST_HEAD_INIT(pa_memimport, p->imports); PA_LLIST_HEAD_INIT(pa_memexport, p->exports); p->free_slots = pa_flist_new(p->n_blocks*2); return p; }
pa_dbusobj_server_lookup *pa_dbusobj_server_lookup_new(pa_core *c) { pa_dbusobj_server_lookup *sl; DBusError error; dbus_error_init(&error); sl = pa_xnew(pa_dbusobj_server_lookup, 1); sl->core = c; sl->path_registered = false; if (!(sl->conn = pa_dbus_bus_get(c, DBUS_BUS_SESSION, &error)) || dbus_error_is_set(&error)) { pa_log_warn("Unable to contact D-Bus: %s: %s", error.name, error.message); goto fail; } if (!dbus_connection_register_object_path(pa_dbus_connection_get(sl->conn), OBJECT_PATH, &vtable, sl)) { pa_log("dbus_connection_register_object_path() failed for " OBJECT_PATH "."); goto fail; } sl->path_registered = true; return sl; fail: dbus_error_free(&error); pa_dbusobj_server_lookup_free(sl); return NULL; }
static pa_autoload_entry* entry_new(pa_core *c, const char *name) { pa_autoload_entry *e = NULL; pa_core_assert_ref(c); pa_assert(name); if (c->autoload_hashmap && (e = pa_hashmap_get(c->autoload_hashmap, name))) return NULL; e = pa_xnew(pa_autoload_entry, 1); e->core = c; e->name = pa_xstrdup(name); e->module = e->argument = NULL; e->in_action = 0; if (!c->autoload_hashmap) c->autoload_hashmap = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); pa_assert(c->autoload_hashmap); pa_hashmap_put(c->autoload_hashmap, e->name, e); if (!c->autoload_idxset) c->autoload_idxset = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); pa_idxset_put(c->autoload_idxset, e, &e->index); pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_AUTOLOAD|PA_SUBSCRIPTION_EVENT_NEW, e->index); return e; }
pa_smoother* pa_smoother_new( uint64_t adjust_time, uint64_t history_time, bool monotonic, bool smoothing, unsigned min_history, uint64_t time_offset, bool paused) { pa_smoother *s; pa_assert(adjust_time > 0); pa_assert(history_time > 0); pa_assert(min_history >= 2); pa_assert(min_history <= HISTORY_MAX); s = pa_xnew(pa_smoother, 1); s->adjust_time = adjust_time; s->history_time = history_time; s->min_history = min_history; s->monotonic = monotonic; s->smoothing = smoothing; pa_smoother_reset(s, time_offset, paused); return s; }
static pa_defer_event* glib_defer_new( pa_mainloop_api*m, pa_defer_event_cb_t cb, void *userdata) { pa_defer_event *e; pa_glib_mainloop *g; g_assert(m); g_assert(m->userdata); g_assert(cb); g = m->userdata; e = pa_xnew(pa_defer_event, 1); e->mainloop = g; e->dead = 0; e->enabled = 1; g->n_enabled_defer_events++; e->callback = cb; e->userdata = userdata; e->destroy_callback = NULL; PA_LLIST_PREPEND(pa_defer_event, g->defer_events, e); return e; }
pa_fdsem *pa_fdsem_new_shm(pa_fdsem_data *data, int* event_fd) { pa_fdsem *f = NULL; pa_assert(data); pa_assert(event_fd); #ifdef HAVE_SYS_EVENTFD_H f = pa_xnew(pa_fdsem, 1); if ((f->efd = eventfd(0, EFD_CLOEXEC)) < 0) { pa_xfree(f); return NULL; } f->fds[0] = f->fds[1] = -1; f->data = data; pa_atomic_store(&f->data->waiting, 0); pa_atomic_store(&f->data->signalled, 0); pa_atomic_store(&f->data->in_pipe, 0); #endif return f; }
pa_cond *pa_cond_new(void) { pa_cond *c; c = pa_xnew(pa_cond, 1); pa_assert_se(pthread_cond_init(&c->cond, NULL) == 0); return c; }
pa_dbus_wrap_connection* pa_dbus_wrap_connection_new(pa_mainloop_api *m, pa_bool_t use_rtclock, DBusBusType type, DBusError *error) { DBusConnection *conn; pa_dbus_wrap_connection *pconn; char *id; pa_assert(type == DBUS_BUS_SYSTEM || type == DBUS_BUS_SESSION || type == DBUS_BUS_STARTER); if (!(conn = dbus_bus_get_private(type, error))) return NULL; pconn = pa_xnew(pa_dbus_wrap_connection, 1); pconn->mainloop = m; pconn->connection = conn; pconn->use_rtclock = use_rtclock; dbus_connection_set_exit_on_disconnect(conn, FALSE); dbus_connection_set_dispatch_status_function(conn, dispatch_status, pconn, NULL); dbus_connection_set_watch_functions(conn, add_watch, remove_watch, toggle_watch, pconn, NULL); dbus_connection_set_timeout_functions(conn, add_timeout, remove_timeout, toggle_timeout, pconn, NULL); dbus_connection_set_wakeup_main_function(conn, wakeup_main, pconn, NULL); pconn->dispatch_event = pconn->mainloop->defer_new(pconn->mainloop, dispatch_cb, conn); pa_log_debug("Successfully connected to D-Bus %s bus %s as %s", type == DBUS_BUS_SYSTEM ? "system" : (type == DBUS_BUS_SESSION ? "session" : "starter"), pa_strnull((id = dbus_connection_get_server_id(conn))), pa_strnull(dbus_bus_get_unique_name(conn))); dbus_free(id); return pconn; }
pa_mutex* pa_mutex_new(pa_bool_t recursive, pa_bool_t inherit_priority) { pa_mutex *m; pthread_mutexattr_t attr; int r; pa_assert_se(pthread_mutexattr_init(&attr) == 0); if (recursive) pa_assert_se(pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) == 0); #ifdef HAVE_PTHREAD_PRIO_INHERIT if (inherit_priority) pa_assert_se(pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT) == 0); #endif m = pa_xnew(pa_mutex, 1); #ifndef HAVE_PTHREAD_PRIO_INHERIT pa_assert_se(pthread_mutex_init(&m->mutex, &attr) == 0); #else if ((r = pthread_mutex_init(&m->mutex, &attr))) { /* If this failed, then this was probably due to non-available * priority inheritance. In which case we fall back to normal * mutexes. */ pa_assert(r == ENOTSUP && inherit_priority); pa_assert_se(pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_NONE) == 0); pa_assert_se(pthread_mutex_init(&m->mutex, &attr) == 0); } #endif return m; }
/* No lock necessary */ pa_memblock *pa_memblock_new_user(pa_mempool *p, void *d, size_t length, pa_free_cb_t free_cb, bool read_only) { pa_memblock *b; pa_assert(p); pa_assert(d); pa_assert(length); pa_assert(length != (size_t) -1); pa_assert(free_cb); if (!(b = pa_flist_pop(PA_STATIC_FLIST_GET(unused_memblocks)))) b = pa_xnew(pa_memblock, 1); PA_REFCNT_INIT(b); b->pool = p; b->type = PA_MEMBLOCK_USER; b->read_only = read_only; b->is_silence = false; pa_atomic_ptr_store(&b->data, d); b->length = length; pa_atomic_store(&b->n_acquired, 0); pa_atomic_store(&b->please_signal, 0); b->per_type.user.free_cb = free_cb; stat_add(b); return b; }
pa_smoother* pa_smoother_new(pa_usec_t adjust_time, pa_usec_t history_time, pa_bool_t monotonic) { pa_smoother *s; pa_assert(adjust_time > 0); pa_assert(history_time > 0); s = pa_xnew(pa_smoother, 1); s->adjust_time = adjust_time; s->history_time = history_time; s->time_offset = 0; s->monotonic = monotonic; s->px = s->py = 0; s->dp = 1; s->ex = s->ey = 0; s->de = 1; s->history_idx = 0; s->n_history = 0; s->last_y = 0; s->abc_valid = FALSE; s->paused = FALSE; return s; }
pa_shmasyncq *pa_shmasyncq_new(unsigned n_elements, size_t element_size, void *data, int fd[2]) { pa_shmasyncq *l; pa_assert(n_elements > 0); pa_assert(is_power_of_two(n_elements)); pa_assert(element_size > 0); pa_assert(data); pa_assert(fd); l = pa_xnew(pa_shmasyncq, 1); l->data = data; memset(data, 0, PA_SHMASYNCQ_SIZE(n_elements, element_size)); l->data->n_elements = n_elements; l->data->element_size = element_size; if (!(l->read_fdsem = pa_fdsem_new_shm(&d->read_fdsem_data))) { pa_xfree(l); return NULL; } fd[0] = pa_fdsem_get(l->read_fdsem); if (!(l->write_fdsem = pa_fdsem_new(&d->write_fdsem_data, &fd[1]))) { pa_fdsem_free(l->read_fdsem); pa_xfree(l); return NULL; } return l; }
static pa_x11_wrapper* x11_wrapper_new(pa_core *c, const char *name, const char *t) { pa_x11_wrapper*w; Display *d; if (!(d = XOpenDisplay(name))) { pa_log("XOpenDisplay() failed"); return NULL; } w = pa_xnew(pa_x11_wrapper, 1); PA_REFCNT_INIT(w); w->core = c; w->property_name = pa_xstrdup(t); w->display = d; PA_LLIST_HEAD_INIT(pa_x11_client, w->clients); PA_LLIST_HEAD_INIT(pa_x11_internal, w->internals); w->defer_event = c->mainloop->defer_new(c->mainloop, defer_event, w); w->io_event = c->mainloop->io_new(c->mainloop, ConnectionNumber(d), PA_IO_EVENT_INPUT, display_io_event, w); XAddConnectionWatch(d, x11_watch, (XPointer) w); pa_assert_se(pa_shared_set(c, w->property_name, w) >= 0); return w; }
pa_client *pa_client_new(pa_core *core, pa_client_new_data *data) { pa_client *c; pa_core_assert_ref(core); pa_assert(data); if (pa_hook_fire(&core->hooks[PA_CORE_HOOK_CLIENT_NEW], data) < 0) return NULL; c = pa_xnew(pa_client, 1); c->core = core; c->proplist = pa_proplist_copy(data->proplist); c->driver = pa_xstrdup(pa_path_get_filename(data->driver)); c->module = data->module; c->sink_inputs = pa_idxset_new(NULL, NULL); c->source_outputs = pa_idxset_new(NULL, NULL); c->userdata = NULL; c->kill = NULL; c->send_event = NULL; pa_assert_se(pa_idxset_put(core->clients, c, &c->index) >= 0); pa_log_info("Created %u \"%s\"", c->index, pa_strnull(pa_proplist_gets(c->proplist, PA_PROP_APPLICATION_NAME))); pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_CLIENT|PA_SUBSCRIPTION_EVENT_NEW, c->index); pa_hook_fire(&core->hooks[PA_CORE_HOOK_CLIENT_PUT], c); pa_core_check_idle(core); return c; }
pa_format_info* pa_format_info_new(void) { pa_format_info *f = pa_xnew(pa_format_info, 1); f->encoding = PA_ENCODING_INVALID; f->plist = pa_proplist_new(); return f; }
pa_queue* pa_queue_new(void) { pa_queue *q = pa_xnew(pa_queue, 1); q->front = q->back = NULL; q->length = 0; return q; }
pa_strbuf *pa_strbuf_new(void) { pa_strbuf *sb; sb = pa_xnew(pa_strbuf, 1); sb->length = 0; sb->head = sb->tail = NULL; return sb; }
/* Append a new subscription event to the subscription event queue and schedule a main loop event */ void pa_subscription_post(pa_core *c, pa_subscription_event_type_t t, uint32_t idx) { pa_subscription_event *e; pa_assert(c); /* No need for queuing subscriptions of no one is listening */ if (!c->subscriptions) return; if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) != PA_SUBSCRIPTION_EVENT_NEW) { pa_subscription_event *i, *n; /* Check for duplicates */ for (i = c->subscription_event_last; i; i = n) { n = i->prev; /* not the same object type */ if (((t ^ i->type) & PA_SUBSCRIPTION_EVENT_FACILITY_MASK)) continue; /* not the same object */ if (i->index != idx) continue; if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { /* This object is being removed, hence there is no * point in keeping the old events regarding this * entry in the queue. */ free_event(i); pa_log_debug("Dropped redundant event due to remove event."); continue; } if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_CHANGE) { /* This object has changed. If a "new" or "change" event for * this object is still in the queue we can exit. */ pa_log_debug("Dropped redundant event due to change event."); return; } } } e = pa_xnew(pa_subscription_event, 1); e->core = c; e->type = t; e->index = idx; PA_LLIST_INSERT_AFTER(pa_subscription_event, c->subscription_event_queue, c->subscription_event_last, e); c->subscription_event_last = e; #ifdef DEBUG dump_event("Queued", e); #endif sched_event(c); }
pa_mutex* pa_mutex_new(bool recursive, bool inherit_priority) { pa_mutex *m; m = pa_xnew(pa_mutex, 1); InitializeCriticalSection(&m->mutex); return m; }
pa_cond *pa_cond_new(void) { pa_cond *c; c = pa_xnew(pa_cond, 1); c->wait_events = pa_hashmap_new(NULL, NULL); assert(c->wait_events); return c; }
/* No lock necessary */ pa_memblock *pa_memblock_new_pool(pa_mempool *p, size_t length) { pa_memblock *b = NULL; struct mempool_slot *slot; static int mempool_disable = 0; pa_assert(p); pa_assert(length); if (mempool_disable == 0) mempool_disable = getenv("PULSE_MEMPOOL_DISABLE") ? 1 : -1; if (mempool_disable > 0) return NULL; /* If -1 is passed as length we choose the size for the caller: we * take the largest size that fits in one of our slots. */ if (length == (size_t) -1) length = pa_mempool_block_size_max(p); if (p->block_size >= PA_ALIGN(sizeof(pa_memblock)) + length) { if (!(slot = mempool_allocate_slot(p))) return NULL; b = mempool_slot_data(slot); b->type = PA_MEMBLOCK_POOL; pa_atomic_ptr_store(&b->data, (uint8_t*) b + PA_ALIGN(sizeof(pa_memblock))); } else if (p->block_size >= length) { if (!(slot = mempool_allocate_slot(p))) return NULL; if (!(b = pa_flist_pop(PA_STATIC_FLIST_GET(unused_memblocks)))) b = pa_xnew(pa_memblock, 1); b->type = PA_MEMBLOCK_POOL_EXTERNAL; pa_atomic_ptr_store(&b->data, mempool_slot_data(slot)); } else { pa_log_debug("Memory block too large for pool: %lu > %lu", (unsigned long) length, (unsigned long) p->block_size); pa_atomic_inc(&p->stat.n_too_large_for_pool); return NULL; } PA_REFCNT_INIT(b); b->pool = p; b->read_only = b->is_silence = false; b->length = length; pa_atomic_store(&b->n_acquired, 0); pa_atomic_store(&b->please_signal, 0); stat_add(b); return b; }
pa_aupdate *pa_aupdate_new(void) { pa_aupdate *a; a = pa_xnew(pa_aupdate, 1); pa_atomic_store(&a->read_lock, 0); a->write_lock = pa_mutex_new(false, false); a->semaphore = pa_semaphore_new(0); return a; }
pa_tagstruct *pa_tagstruct_new(void) { pa_tagstruct*t; t = pa_xnew(pa_tagstruct, 1); t->data = NULL; t->allocated = t->length = 0; t->rindex = 0; t->type = PA_TAGSTRUCT_DYNAMIC; return t; }
pa_tagstruct *pa_tagstruct_new(void) { pa_tagstruct*t; t = pa_xnew(pa_tagstruct, 1); t->data = t->per_type.appended; t->allocated = MAX_APPENDED_SIZE; t->length = t->rindex = 0; t->type = PA_TAGSTRUCT_APPENDED; return t; }
pa_tagstruct *pa_tagstruct_copy(pa_tagstruct*t) { pa_tagstruct*tc; if (!(tc = pa_flist_pop(PA_STATIC_FLIST_GET(tagstructs)))) tc = pa_xnew(pa_tagstruct, 1); tc->data = pa_xmemdup(t->data, t->length); tc->allocated = t->length; tc->rindex = 0; tc->type = PA_TAGSTRUCT_DYNAMIC; return tc; }
pa_tagstruct *pa_tagstruct_new(void) { pa_tagstruct*t; if (!(t = pa_flist_pop(PA_STATIC_FLIST_GET(tagstructs)))) t = pa_xnew(pa_tagstruct, 1); t->data = t->per_type.appended; t->allocated = MAX_APPENDED_SIZE; t->length = t->rindex = 0; t->type = PA_TAGSTRUCT_APPENDED; return t; }
/* Allocate a new shared property object */ static pa_shared* shared_new(const char *name, void *data) { pa_shared* p; pa_assert(name); pa_assert(data); p = pa_xnew(pa_shared, 1); p->name = pa_xstrdup(name); p->data = data; return p; }
/* Add a new IO source for the specified X11 internal connection */ static pa_x11_internal* x11_internal_add(pa_x11_wrapper *w, int fd) { pa_x11_internal *i; pa_assert(fd >= 0); i = pa_xnew(pa_x11_internal, 1); i->wrapper = w; i->io_event = w->core->mainloop->io_new(w->core->mainloop, fd, PA_IO_EVENT_INPUT, internal_io_event, w); i->fd = fd; PA_LLIST_PREPEND(pa_x11_internal, w->internals, i); return i; }
/* Allocate a new property object */ static pa_property* property_new(const char *name, void *data) { pa_property* p; pa_assert(name); pa_assert(data); p = pa_xnew(pa_property, 1); p->name = pa_xstrdup(name); p->data = data; return p; }
pa_prioq *pa_prioq_new(pa_compare_func_t compare_func) { pa_prioq *q; q = pa_xnew(pa_prioq, 1); q->compare_func = compare_func; q->n_items = 0; q->n_allocated = 64; q->items = pa_xnew(pa_prioq_item*, q->n_allocated); return q; }