char *pa_autoload_list_to_string(pa_core *c) { pa_strbuf *s; pa_assert(c); s = pa_strbuf_new(); pa_strbuf_printf(s, "%u autoload entries available.\n", c->autoload_hashmap ? pa_hashmap_size(c->autoload_hashmap) : 0); if (c->autoload_hashmap) { pa_autoload_entry *e; void *state = NULL; while ((e = pa_hashmap_iterate(c->autoload_hashmap, &state, NULL))) { pa_strbuf_printf( s, " name: <%s>\n\ttype: <%s>\n\tindex: <%u>\n\tmodule_name: <%s>\n\targuments: <%s>\n", e->name, e->type == PA_NAMEREG_SOURCE ? "source" : "sink", e->index, e->module, e->argument ? e->argument : ""); } } return pa_strbuf_tostring_free(s); }
/* Self-locked. Not multiple-caller safe */ void pa_memimport_free(pa_memimport *i) { pa_memexport *e; pa_memblock *b; pa_assert(i); pa_mutex_lock(i->mutex); while ((b = pa_hashmap_first(i->blocks))) memblock_replace_import(b); pa_assert(pa_hashmap_size(i->segments) == 0); pa_mutex_unlock(i->mutex); pa_mutex_lock(i->pool->mutex); /* If we've exported this block further we need to revoke that export */ for (e = i->pool->exports; e; e = e->next) memexport_revoke_blocks(e, i); PA_LLIST_REMOVE(pa_memimport, i->pool->imports, i); pa_mutex_unlock(i->pool->mutex); pa_hashmap_free(i->blocks); pa_hashmap_free(i->segments); pa_mutex_free(i->mutex); pa_xfree(i); }
static void make_room(pa_hashmap *cache) { pa_assert(cache); while (pa_hashmap_size(cache) >= MAX_CACHE_SIZE) { struct rule *r; pa_assert_se(r = pa_hashmap_steal_first(cache)); rule_free(r); } }
void pa_property_cleanup(pa_core *c) { pa_assert(c); if (!c->properties) return; pa_assert(!pa_hashmap_size(c->properties)); pa_hashmap_free(c->properties, NULL, NULL); c->properties = NULL; }
/* 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; }
/* Should be called locked */ static pa_memimport_segment* segment_attach(pa_memimport *i, uint32_t shm_id) { pa_memimport_segment* seg; if (pa_hashmap_size(i->segments) >= PA_MEMIMPORT_SEGMENTS_MAX) return NULL; seg = pa_xnew0(pa_memimport_segment, 1); if (pa_shm_attach_ro(&seg->memory, shm_id) < 0) { pa_xfree(seg); return NULL; } seg->import = i; seg->trap = pa_memtrap_add(seg->memory.ptr, seg->memory.size); pa_hashmap_put(i->segments, PA_UINT32_TO_PTR(seg->memory.id), seg); return seg; }
void pa_cond_signal(pa_cond *c, int broadcast) { assert(c); if (pa_hashmap_size(c->wait_events) == 0) return; if (broadcast) SetEvent(pa_hashmap_first(c->wait_events)); else { void *iter; const void *key; HANDLE event; iter = NULL; while (1) { pa_hashmap_iterate(c->wait_events, &iter, &key); if (key == NULL) break; event = (HANDLE)pa_hashmap_get(c->wait_events, key); SetEvent(event); } } }
int pa__init(pa_module *m) { struct userdata *u = NULL; pa_modargs *ma; struct udev_enumerate *enumerate = NULL; struct udev_list_entry *item = NULL, *first = NULL; int fd; bool use_tsched = true, fixed_latency_range = false, ignore_dB = false, deferred_volume = m->core->deferred_volume; bool use_ucm = true; pa_assert(m); if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { pa_log("Failed to parse module arguments"); goto fail; } m->userdata = u = pa_xnew0(struct userdata, 1); u->core = m->core; u->devices = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL, (pa_free_cb_t) device_free); u->inotify_fd = -1; if (pa_modargs_get_value_boolean(ma, "tsched", &use_tsched) < 0) { pa_log("Failed to parse tsched= argument."); goto fail; } u->use_tsched = use_tsched; if (pa_modargs_get_value(ma, "tsched_buffer_size", NULL)) { if (pa_modargs_get_value_u32(ma, "tsched_buffer_size", &u->tsched_buffer_size) < 0) { pa_log("Failed to parse tsched_buffer_size= argument."); goto fail; } u->tsched_buffer_size_valid = true; } if (pa_modargs_get_value_boolean(ma, "fixed_latency_range", &fixed_latency_range) < 0) { pa_log("Failed to parse fixed_latency_range= argument."); goto fail; } u->fixed_latency_range = fixed_latency_range; if (pa_modargs_get_value_boolean(ma, "ignore_dB", &ignore_dB) < 0) { pa_log("Failed to parse ignore_dB= argument."); goto fail; } u->ignore_dB = ignore_dB; if (pa_modargs_get_value_boolean(ma, "deferred_volume", &deferred_volume) < 0) { pa_log("Failed to parse deferred_volume= argument."); goto fail; } u->deferred_volume = deferred_volume; if (pa_modargs_get_value_boolean(ma, "use_ucm", &use_ucm) < 0) { pa_log("Failed to parse use_ucm= argument."); goto fail; } u->use_ucm = use_ucm; if (!(u->udev = udev_new())) { pa_log("Failed to initialize udev library."); goto fail; } if (setup_inotify(u) < 0) goto fail; if (!(u->monitor = udev_monitor_new_from_netlink(u->udev, "udev"))) { pa_log("Failed to initialize monitor."); goto fail; } if (udev_monitor_filter_add_match_subsystem_devtype(u->monitor, "sound", NULL) < 0) { pa_log("Failed to subscribe to sound devices."); goto fail; } errno = 0; if (udev_monitor_enable_receiving(u->monitor) < 0) { pa_log("Failed to enable monitor: %s", pa_cstrerror(errno)); if (errno == EPERM) pa_log_info("Most likely your kernel is simply too old and " "allows only privileged processes to listen to device events. " "Please upgrade your kernel to at least 2.6.30."); goto fail; } if ((fd = udev_monitor_get_fd(u->monitor)) < 0) { pa_log("Failed to get udev monitor fd."); goto fail; } pa_assert_se(u->udev_io = u->core->mainloop->io_new(u->core->mainloop, fd, PA_IO_EVENT_INPUT, monitor_cb, u)); if (!(enumerate = udev_enumerate_new(u->udev))) { pa_log("Failed to initialize udev enumerator."); goto fail; } if (udev_enumerate_add_match_subsystem(enumerate, "sound") < 0) { pa_log("Failed to match to subsystem."); goto fail; } if (udev_enumerate_scan_devices(enumerate) < 0) { pa_log("Failed to scan for devices."); goto fail; } first = udev_enumerate_get_list_entry(enumerate); udev_list_entry_foreach(item, first) process_path(u, udev_list_entry_get_name(item)); udev_enumerate_unref(enumerate); pa_log_info("Found %u cards.", pa_hashmap_size(u->devices)); pa_modargs_free(ma); return 0; fail: if (enumerate) udev_enumerate_unref(enumerate); if (ma) pa_modargs_free(ma); pa__done(m); return -1; }