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); }
void pa_core_maybe_vacuum(pa_core *c) { pa_assert(c); if (pa_idxset_isempty(c->sink_inputs) && pa_idxset_isempty(c->source_outputs)) { pa_log_debug("Hmm, no streams around, trying to vacuum."); } else { pa_sink *si; pa_source *so; uint32_t idx; idx = 0; PA_IDXSET_FOREACH(si, c->sinks, idx) if (pa_sink_get_state(si) != PA_SINK_SUSPENDED) return; idx = 0; PA_IDXSET_FOREACH(so, c->sources, idx) if (pa_source_get_state(so) != PA_SOURCE_SUSPENDED) return; pa_log_info("All sinks and sources are suspended, vacuuming memory"); } pa_mempool_vacuum(c->mempool); if (c->rw_mempool) pa_mempool_vacuum(c->rw_mempool); }
static void core_free(pa_object *o) { pa_core *c = PA_CORE(o); int j; pa_assert(c); c->state = PA_CORE_SHUTDOWN; /* Note: All modules and samples in the cache should be unloaded before * we get here */ pa_assert(pa_idxset_isempty(c->scache)); pa_idxset_free(c->scache, NULL); pa_assert(pa_idxset_isempty(c->modules)); pa_idxset_free(c->modules, NULL); pa_assert(pa_idxset_isempty(c->clients)); pa_idxset_free(c->clients, NULL); pa_assert(pa_idxset_isempty(c->cards)); pa_idxset_free(c->cards, NULL); pa_assert(pa_idxset_isempty(c->sinks)); pa_idxset_free(c->sinks, NULL); pa_assert(pa_idxset_isempty(c->sources)); pa_idxset_free(c->sources, NULL); pa_assert(pa_idxset_isempty(c->source_outputs)); pa_idxset_free(c->source_outputs, NULL); pa_assert(pa_idxset_isempty(c->sink_inputs)); pa_idxset_free(c->sink_inputs, NULL); pa_assert(pa_hashmap_isempty(c->namereg)); pa_hashmap_free(c->namereg); pa_assert(pa_hashmap_isempty(c->shared)); pa_hashmap_free(c->shared); pa_assert(pa_hashmap_isempty(c->modules_pending_unload)); pa_hashmap_free(c->modules_pending_unload); pa_subscription_free_all(c); if (c->exit_event) c->mainloop->time_free(c->exit_event); pa_assert(!c->default_source); pa_assert(!c->default_sink); pa_silence_cache_done(&c->silence_cache); if (c->rw_mempool) pa_mempool_free(c->rw_mempool); pa_mempool_free(c->mempool); for (j = 0; j < PA_CORE_HOOK_MAX; j++) pa_hook_done(&c->hooks[j]); for (j = 0; j < PA_ACCESS_HOOK_MAX; j++) pa_hook_done(&c->access[j]); pa_xfree(c); }
char *pa_card_list_to_string(pa_core *c) { pa_strbuf *s; pa_card *card; uint32_t idx = PA_IDXSET_INVALID; pa_assert(c); s = pa_strbuf_new(); pa_strbuf_printf(s, "%u card(s) available.\n", pa_idxset_size(c->cards)); for (card = pa_idxset_first(c->cards, &idx); card; card = pa_idxset_next(c->cards, &idx)) { char *t; pa_sink *sink; pa_source *source; uint32_t sidx; pa_strbuf_printf( s, " index: %u\n" "\tname: <%s>\n" "\tdriver: <%s>\n", card->index, card->name, card->driver); if (card->module) pa_strbuf_printf(s, "\towner module: %u\n", card->module->index); t = pa_proplist_to_string_sep(card->proplist, "\n\t\t"); pa_strbuf_printf(s, "\tproperties:\n\t\t%s\n", t); pa_xfree(t); if (card->profiles) { pa_card_profile *p; void *state; pa_strbuf_puts(s, "\tprofiles:\n"); PA_HASHMAP_FOREACH(p, card->profiles, state) pa_strbuf_printf(s, "\t\t%s: %s (priority %u)\n", p->name, p->description, p->priority); } if (card->active_profile) pa_strbuf_printf( s, "\tactive profile: <%s>\n", card->active_profile->name); if (!pa_idxset_isempty(card->sinks)) { pa_strbuf_puts(s, "\tsinks:\n"); for (sink = pa_idxset_first(card->sinks, &sidx); sink; sink = pa_idxset_next(card->sinks, &sidx)) pa_strbuf_printf(s, "\t\t%s/#%u: %s\n", sink->name, sink->index, pa_strna(pa_proplist_gets(sink->proplist, PA_PROP_DEVICE_DESCRIPTION))); } if (!pa_idxset_isempty(card->sources)) { pa_strbuf_puts(s, "\tsources:\n"); for (source = pa_idxset_first(card->sources, &sidx); source; source = pa_idxset_next(card->sources, &sidx)) pa_strbuf_printf(s, "\t\t%s/#%u: %s\n", source->name, source->index, pa_strna(pa_proplist_gets(source->proplist, PA_PROP_DEVICE_DESCRIPTION))); } append_port_list(s, card->ports); } return pa_strbuf_tostring_free(s); }