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; }
void pa_client_free(pa_client *c) { pa_core *core; pa_assert(c); pa_assert(c->core); core = c->core; pa_hook_fire(&core->hooks[PA_CORE_HOOK_CLIENT_UNLINK], c); pa_idxset_remove_by_data(c->core->clients, c, NULL); pa_log_info("Freed %u \"%s\"", c->index, pa_strnull(pa_proplist_gets(c->proplist, PA_PROP_APPLICATION_NAME))); pa_subscription_post(c->core, PA_SUBSCRIPTION_EVENT_CLIENT|PA_SUBSCRIPTION_EVENT_REMOVE, c->index); pa_assert(pa_idxset_isempty(c->sink_inputs)); pa_idxset_free(c->sink_inputs, NULL); pa_assert(pa_idxset_isempty(c->source_outputs)); pa_idxset_free(c->source_outputs, NULL); pa_proplist_free(c->proplist); pa_xfree(c->driver); pa_xfree(c); pa_core_check_idle(core); }
pa_core* pa_core_new(pa_mainloop_api *m, bool shared, size_t shm_size) { pa_core* c; pa_mempool *pool; int j; pa_assert(m); if (shared) { if (!(pool = pa_mempool_new(shared, shm_size))) { pa_log_warn("Failed to allocate shared memory pool. Falling back to a normal memory pool."); shared = false; } } if (!shared) { if (!(pool = pa_mempool_new(shared, shm_size))) { pa_log("pa_mempool_new() failed."); return NULL; } } c = pa_msgobject_new(pa_core); c->parent.parent.free = core_free; c->parent.process_msg = core_process_msg; c->state = PA_CORE_STARTUP; c->mainloop = m; c->clients = pa_idxset_new(NULL, NULL); c->cards = pa_idxset_new(NULL, NULL); c->sinks = pa_idxset_new(NULL, NULL); c->sources = pa_idxset_new(NULL, NULL); c->sink_inputs = pa_idxset_new(NULL, NULL); c->source_outputs = pa_idxset_new(NULL, NULL); c->modules = pa_idxset_new(NULL, NULL); c->scache = pa_idxset_new(NULL, NULL); c->namereg = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); c->shared = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); c->default_source = NULL; c->default_sink = NULL; c->default_sample_spec.format = PA_SAMPLE_S16NE; c->default_sample_spec.rate = 44100; c->default_sample_spec.channels = 2; pa_channel_map_init_extend(&c->default_channel_map, c->default_sample_spec.channels, PA_CHANNEL_MAP_DEFAULT); c->default_n_fragments = 4; c->default_fragment_size_msec = 25; c->deferred_volume_safety_margin_usec = 8000; c->deferred_volume_extra_delay_usec = 0; c->module_defer_unload_event = NULL; c->modules_pending_unload = pa_hashmap_new(NULL, NULL); c->subscription_defer_event = NULL; PA_LLIST_HEAD_INIT(pa_subscription, c->subscriptions); PA_LLIST_HEAD_INIT(pa_subscription_event, c->subscription_event_queue); c->subscription_event_last = NULL; c->mempool = pool; pa_silence_cache_init(&c->silence_cache); if (shared && !(c->rw_mempool = pa_mempool_new(shared, shm_size))) pa_log_warn("Failed to allocate shared writable memory pool."); if (c->rw_mempool) pa_mempool_set_is_remote_writable(c->rw_mempool, true); c->exit_event = NULL; c->scache_auto_unload_event = NULL; c->exit_idle_time = -1; c->scache_idle_time = 20; c->flat_volumes = true; c->disallow_module_loading = false; c->disallow_exit = false; c->running_as_daemon = false; c->realtime_scheduling = false; c->realtime_priority = 5; c->disable_remixing = false; c->disable_lfe_remixing = false; c->lfe_crossover_freq = 120; c->deferred_volume = true; c->resample_method = PA_RESAMPLER_SPEEX_FLOAT_BASE + 1; for (j = 0; j < PA_CORE_HOOK_MAX; j++) pa_hook_init(&c->hooks[j], c); for (j = 0; j < PA_ACCESS_HOOK_MAX; j++) pa_hook_init(&c->access[j], c); pa_random(&c->cookie, sizeof(c->cookie)); #ifdef SIGPIPE pa_check_signal_is_blocked(SIGPIPE); #endif pa_core_check_idle(c); c->state = PA_CORE_RUNNING; return c; }