pa_auth_cookie* pa_auth_cookie_get(pa_core *core, const char *cn, bool create, size_t size) { pa_auth_cookie *c; char *t; pa_assert(core); pa_assert(size > 0); t = pa_sprintf_malloc("auth-cookie%s%s", cn ? "@" : "", cn ? cn : ""); if ((c = pa_shared_get(core, t))) { pa_xfree(t); if (c->size != size) return NULL; return pa_auth_cookie_ref(c); } c = pa_xmalloc(PA_ALIGN(sizeof(pa_auth_cookie)) + size); PA_REFCNT_INIT(c); c->core = core; c->name = t; c->size = size; pa_assert_se(pa_shared_set(core, t, c) >= 0); if (pa_authkey_load(cn, create, (uint8_t*) c + PA_ALIGN(sizeof(pa_auth_cookie)), size) < 0) { pa_auth_cookie_unref(c); return NULL; } return c; }
pa_auth_cookie *pa_auth_cookie_create(pa_core *core, const void *data, size_t size) { pa_auth_cookie *c; char *t; pa_assert(core); pa_assert(data); pa_assert(size > 0); t = pa_xstrdup("auth-cookie"); if ((c = pa_shared_get(core, t))) { pa_xfree(t); if (c->size != size) return NULL; return pa_auth_cookie_ref(c); } c = pa_xmalloc(PA_ALIGN(sizeof(pa_auth_cookie)) + size); PA_REFCNT_INIT(c); c->core = core; c->name = t; c->size = size; pa_assert_se(pa_shared_set(core, t, c) >= 0); memcpy((uint8_t *) c + PA_ALIGN(sizeof(pa_auth_cookie)), data, size); return c; }
/* 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; }
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_context *pa_context_new_with_proplist(pa_mainloop_api *mainloop, const char *name, pa_proplist *p) { pa_context *c; pa_assert(mainloop); if (pa_detect_fork()) return NULL; pa_init_i18n(); c = pa_xnew0(pa_context, 1); PA_REFCNT_INIT(c); c->proplist = p ? pa_proplist_copy(p) : pa_proplist_new(); if (name) pa_proplist_sets(c->proplist, PA_PROP_APPLICATION_NAME, name); #ifdef HAVE_DBUS c->system_bus = c->session_bus = NULL; #endif c->mainloop = mainloop; c->playback_streams = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); c->record_streams = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); c->client_index = PA_INVALID_INDEX; c->use_rtclock = pa_mainloop_is_our_api(mainloop); PA_LLIST_HEAD_INIT(pa_stream, c->streams); PA_LLIST_HEAD_INIT(pa_operation, c->operations); c->error = PA_OK; c->state = PA_CONTEXT_UNCONNECTED; reset_callbacks(c); #ifndef MSG_NOSIGNAL #ifdef SIGPIPE pa_check_signal_is_blocked(SIGPIPE); #endif #endif c->conf = pa_client_conf_new(); pa_client_conf_load(c->conf, true, true); c->srb_template.readfd = -1; c->srb_template.writefd = -1; if (!(c->mempool = pa_mempool_new(!c->conf->disable_shm, c->conf->shm_size))) { if (!c->conf->disable_shm) c->mempool = pa_mempool_new(false, c->conf->shm_size); if (!c->mempool) { context_free(c); return NULL; } } 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_simple_options* pa_simple_options_new(void) { pa_simple_options *o; o = pa_xnew0(pa_simple_options, 1); PA_REFCNT_INIT(o); o->record = FALSE; o->playback = TRUE; return o; }
pa_simple_options* pa_simple_options_new(void) { pa_simple_options *o; o = pa_xnew0(pa_simple_options, 1); PA_REFCNT_INIT(o); o->record = false; o->playback = true; return o; }
static pa_dbus_connection* dbus_connection_new(pa_core *c, pa_dbus_wrap_connection *conn, const char *name) { pa_dbus_connection *pconn; pconn = pa_xnew(pa_dbus_connection, 1); PA_REFCNT_INIT(pconn); pconn->core = c; pconn->property_name = name; pconn->connection = conn; pa_shared_set(c, name, pconn); return pconn; }
static pa_simple_protocol* simple_protocol_new(pa_core *c) { pa_simple_protocol *p; pa_assert(c); p = pa_xnew(pa_simple_protocol, 1); PA_REFCNT_INIT(p); p->core = c; p->connections = pa_idxset_new(NULL, NULL); pa_assert_se(pa_shared_set(c, "simple-protocol", p) >= 0); return p; }
/* Self-locked */ pa_memblock* pa_memimport_get(pa_memimport *i, uint32_t block_id, uint32_t shm_id, size_t offset, size_t size) { pa_memblock *b = NULL; pa_memimport_segment *seg; pa_assert(i); pa_mutex_lock(i->mutex); if ((b = pa_hashmap_get(i->blocks, PA_UINT32_TO_PTR(block_id)))) { pa_memblock_ref(b); goto finish; } if (pa_hashmap_size(i->blocks) >= PA_MEMIMPORT_SLOTS_MAX) goto finish; if (!(seg = pa_hashmap_get(i->segments, PA_UINT32_TO_PTR(shm_id)))) if (!(seg = segment_attach(i, shm_id))) goto finish; if (offset+size > seg->memory.size) goto finish; if (!(b = pa_flist_pop(PA_STATIC_FLIST_GET(unused_memblocks)))) b = pa_xnew(pa_memblock, 1); PA_REFCNT_INIT(b); b->pool = i->pool; b->type = PA_MEMBLOCK_IMPORTED; b->read_only = true; b->is_silence = false; pa_atomic_ptr_store(&b->data, (uint8_t*) seg->memory.ptr + offset); b->length = size; pa_atomic_store(&b->n_acquired, 0); pa_atomic_store(&b->please_signal, 0); b->per_type.imported.id = block_id; b->per_type.imported.segment = seg; pa_hashmap_put(i->blocks, PA_UINT32_TO_PTR(block_id), b); seg->n_blocks++; stat_add(b); finish: pa_mutex_unlock(i->mutex); return b; }
pa_packet* pa_packet_new_dynamic(void* data, size_t length) { pa_packet *p; pa_assert(data); pa_assert(length > 0); if (!(p = pa_flist_pop(PA_STATIC_FLIST_GET(packets)))) p = pa_xnew(pa_packet, 1); PA_REFCNT_INIT(p); p->length = length; p->data = data; p->type = PA_PACKET_DYNAMIC; return p; }
pa_socket_server* pa_socket_server_new(pa_mainloop_api *m, int fd) { pa_socket_server *s; pa_assert(m); pa_assert(fd >= 0); s = pa_xnew0(pa_socket_server, 1); PA_REFCNT_INIT(s); s->fd = fd; s->mainloop = m; pa_assert_se(s->io_event = m->io_new(m, fd, PA_IO_EVENT_INPUT, callback, s)); s->type = SOCKET_SERVER_GENERIC; return s; }
pa_asyncmsgq *pa_asyncmsgq_new(unsigned size) { pa_asyncq *asyncq; pa_asyncmsgq *a; asyncq = pa_asyncq_new(size); if (!asyncq) return NULL; a = pa_xnew(pa_asyncmsgq, 1); PA_REFCNT_INIT(a); a->asyncq = asyncq; pa_assert_se(a->mutex = pa_mutex_new(false, true)); a->current = NULL; return a; }
pa_packet* pa_packet_new(size_t length) { pa_packet *p; pa_assert(length > 0); if (!(p = pa_flist_pop(PA_STATIC_FLIST_GET(packets)))) p = pa_xnew(pa_packet, 1); PA_REFCNT_INIT(p); p->length = length; if (length > MAX_APPENDED_SIZE) { p->data = pa_xmalloc(length); p->type = PA_PACKET_DYNAMIC; } else { p->data = p->per_type.appended; p->type = PA_PACKET_APPENDED; } return p; }
/* No lock necessary */ pa_memblock *pa_memblock_new_fixed(pa_mempool *p, void *d, size_t length, int read_only) { pa_memblock *b; pa_assert(p); pa_assert(d); pa_assert(length != (size_t) -1); pa_assert(length > 0); 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_FIXED; b->read_only = read_only; pa_atomic_ptr_store(&b->data, d); b->length = length; pa_atomic_store(&b->n_acquired, 0); pa_atomic_store(&b->please_signal, 0); stat_add(b); return b; }
/* No lock necessary */ static pa_memblock *memblock_new_appended(pa_mempool *p, size_t length) { pa_memblock *b; pa_assert(p); pa_assert(length); /* If -1 is passed as length we choose the size for the caller. */ if (length == (size_t) -1) length = pa_mempool_block_size_max(p); b = pa_xmalloc(PA_ALIGN(sizeof(pa_memblock)) + length); PA_REFCNT_INIT(b); b->pool = p; b->type = PA_MEMBLOCK_APPENDED; b->read_only = b->is_silence = false; pa_atomic_ptr_store(&b->data, (uint8_t*) b + PA_ALIGN(sizeof(pa_memblock))); b->length = length; pa_atomic_store(&b->n_acquired, 0); pa_atomic_store(&b->please_signal, 0); stat_add(b); return b; }
pa_context *pa_context_new_with_proplist(pa_mainloop_api *mainloop, const char *name, pa_proplist *p) { pa_context *c; pa_mem_type_t type; pa_assert(mainloop); if (pa_detect_fork()) return NULL; pa_init_i18n(); c = pa_xnew0(pa_context, 1); PA_REFCNT_INIT(c); c->proplist = p ? pa_proplist_copy(p) : pa_proplist_new(); if (name) pa_proplist_sets(c->proplist, PA_PROP_APPLICATION_NAME, name); #ifdef HAVE_DBUS c->system_bus = c->session_bus = NULL; #endif c->mainloop = mainloop; c->playback_streams = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); c->record_streams = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); c->client_index = PA_INVALID_INDEX; c->use_rtclock = pa_mainloop_is_our_api(mainloop); PA_LLIST_HEAD_INIT(pa_stream, c->streams); PA_LLIST_HEAD_INIT(pa_operation, c->operations); c->error = PA_OK; c->state = PA_CONTEXT_UNCONNECTED; reset_callbacks(c); #ifndef MSG_NOSIGNAL #ifdef SIGPIPE pa_check_signal_is_blocked(SIGPIPE); #endif #endif c->conf = pa_client_conf_new(); pa_client_conf_load(c->conf, true, true); c->srb_template.readfd = -1; c->srb_template.writefd = -1; c->memfd_on_local = (!c->conf->disable_memfd && pa_memfd_is_locally_supported()); type = (c->conf->disable_shm) ? PA_MEM_TYPE_PRIVATE : ((!c->memfd_on_local) ? PA_MEM_TYPE_SHARED_POSIX : PA_MEM_TYPE_SHARED_MEMFD); if (!(c->mempool = pa_mempool_new(type, c->conf->shm_size, true))) { if (!c->conf->disable_shm) { pa_log_warn("Failed to allocate shared memory pool. Falling back to a normal private one."); c->mempool = pa_mempool_new(PA_MEM_TYPE_PRIVATE, c->conf->shm_size, true); } if (!c->mempool) { context_free(c); return NULL; } } return c; }
pa_reserve_monitor_wrapper* pa_reserve_monitor_wrapper_get(pa_core *c, const char *device_name) { pa_reserve_monitor_wrapper *w; int k; char *t; #ifdef HAVE_DBUS DBusError error; dbus_error_init(&error); #endif pa_assert(c); pa_assert(device_name); t = pa_sprintf_malloc("reserve-monitor-wrapper@%s", device_name); if ((w = pa_shared_get(c, t))) { pa_xfree(t); pa_assert(PA_REFCNT_VALUE(w) >= 1); PA_REFCNT_INC(w); return w; } w = pa_xnew0(pa_reserve_monitor_wrapper, 1); PA_REFCNT_INIT(w); w->core = c; pa_hook_init(&w->hook, w); w->shared_name = t; pa_assert_se(pa_shared_set(c, w->shared_name, w) >= 0); #ifdef HAVE_DBUS if (!(w->connection = pa_dbus_bus_get(c, DBUS_BUS_SESSION, &error)) || dbus_error_is_set(&error)) { pa_log_debug("Unable to contact D-Bus session bus: %s: %s", error.name, error.message); /* We don't treat this as error here because we want allow PA * to run even when no session bus is available. */ return w; } if ((k = rm_watch( &w->monitor, pa_dbus_connection_get(w->connection), device_name, change_cb, NULL)) < 0) { pa_log_debug("Failed to create watch on device '%s': %s", device_name, pa_cstrerror(-k)); goto fail; } pa_log_debug("Successfully create reservation lock monitor for device '%s'", device_name); rm_set_userdata(w->monitor, w); return w; fail: dbus_error_free(&error); reserve_monitor_wrapper_free(w); return NULL; #else return w; #endif }
pa_reserve_wrapper* pa_reserve_wrapper_get(pa_core *c, const char *device_name) { pa_reserve_wrapper *r; int k; char *t; #ifdef HAVE_DBUS DBusError error; dbus_error_init(&error); #endif pa_assert(c); pa_assert(device_name); t = pa_sprintf_malloc("reserve-wrapper@%s", device_name); if ((r = pa_shared_get(c, t))) { pa_xfree(t); pa_assert(PA_REFCNT_VALUE(r) >= 1); PA_REFCNT_INC(r); return r; } r = pa_xnew0(pa_reserve_wrapper, 1); PA_REFCNT_INIT(r); r->core = c; pa_hook_init(&r->hook, r); r->shared_name = t; pa_assert_se(pa_shared_set(c, r->shared_name, r) >= 0); #ifdef HAVE_DBUS if (!(r->connection = pa_dbus_bus_get(c, DBUS_BUS_SESSION, &error)) || dbus_error_is_set(&error)) { pa_log_debug("Unable to contact D-Bus session bus: %s: %s", error.name, error.message); /* We don't treat this as error here because we want allow PA * to run even when no session bus is available. */ return r; } if ((k = rd_acquire( &r->device, pa_dbus_connection_get(r->connection), device_name, _("PulseAudio Sound Server"), 0, request_cb, NULL)) < 0) { if (k == -EBUSY) { pa_log_debug("Device '%s' already locked.", device_name); goto fail; } else { pa_log_debug("Failed to acquire reservation lock on device '%s': %s", device_name, pa_cstrerror(-k)); return r; } } pa_log_debug("Successfully acquired reservation lock on device '%s'", device_name); rd_set_userdata(r->device, r); return r; fail: dbus_error_free(&error); reserve_wrapper_free(r); return NULL; #else return r; #endif }