From 1bcec3ef5b83ca72c7d32e553566698607bae0e2 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 27 Oct 2004 16:23:23 +0000 Subject: make autoload list use idxset git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@262 fefdeb5f-60dc-0310-8127-8f9354f1896f --- doc/todo | 3 +- polyp/autoload.c | 70 +++++++++++++++++++++++++++++++++++------ polyp/autoload.h | 9 ++++-- polyp/cli-command.c | 4 +-- polyp/cli-text.c | 5 +-- polyp/core.c | 2 +- polyp/core.h | 2 +- polyp/pactl.c | 3 +- polyp/polyplib-introspect.c | 77 ++++++++++++++++++++++++++++++++++++++++++--- polyp/polyplib-introspect.h | 18 ++++++++--- polyp/protocol-native.c | 54 ++++++++++++++++++++++--------- 11 files changed, 204 insertions(+), 43 deletions(-) diff --git a/doc/todo b/doc/todo index fa97b4a3..1ffdee49 100644 --- a/doc/todo +++ b/doc/todo @@ -1,6 +1,6 @@ *** $Id$ *** -*** 0.6 **** +*** 0.7 **** - per-channel volume - unix socket directories include user name - add sample directory @@ -9,7 +9,6 @@ - improve module-oss-mmap latency measurement - filter capture data in client through alignment - add radio module -- make autoload list use idxset - add sync API - make most buffer sizes dependant on the sample type diff --git a/polyp/autoload.c b/polyp/autoload.c index 12cd1f91..d6207962 100644 --- a/polyp/autoload.c +++ b/polyp/autoload.c @@ -45,6 +45,14 @@ static void entry_free(struct pa_autoload_entry *e) { pa_xfree(e); } +static void entry_remove_and_free(struct pa_autoload_entry *e) { + assert(e && e->core); + + pa_idxset_remove_by_data(e->core->autoload_idxset, e, NULL); + pa_hashmap_remove(e->core->autoload_hashmap, e->name); + entry_free(e); +} + static struct pa_autoload_entry* entry_new(struct pa_core *c, const char *name) { struct pa_autoload_entry *e = NULL; assert(c && name); @@ -64,12 +72,16 @@ static struct pa_autoload_entry* entry_new(struct pa_core *c, const char *name) pa_hashmap_put(c->autoload_hashmap, e->name, e); - pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_AUTOLOAD|PA_SUBSCRIPTION_EVENT_NEW, PA_INVALID_INDEX); + 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; } -int pa_autoload_add(struct pa_core *c, const char*name, enum pa_namereg_type type, const char*module, const char *argument) { +int pa_autoload_add(struct pa_core *c, const char*name, enum pa_namereg_type type, const char*module, const char *argument, uint32_t *index) { struct pa_autoload_entry *e = NULL; assert(c && name && module && (type == PA_NAMEREG_SINK || type == PA_NAMEREG_SOURCE)); @@ -79,18 +91,32 @@ int pa_autoload_add(struct pa_core *c, const char*name, enum pa_namereg_type typ e->module = pa_xstrdup(module); e->argument = pa_xstrdup(argument); e->type = type; + + if (index) + *index = e->index; + return 0; } -int pa_autoload_remove(struct pa_core *c, const char*name, enum pa_namereg_type type) { +int pa_autoload_remove_by_name(struct pa_core *c, const char*name, enum pa_namereg_type type) { struct pa_autoload_entry *e; assert(c && name && type); - if (!c->autoload_hashmap || !(e = pa_hashmap_get(c->autoload_hashmap, name))) + if (!c->autoload_hashmap || !(e = pa_hashmap_get(c->autoload_hashmap, name)) || e->type != type) return -1; - pa_hashmap_remove(c->autoload_hashmap, e->name); - entry_free(e); + entry_remove_and_free(e); + return 0; +} + +int pa_autoload_remove_by_index(struct pa_core *c, uint32_t index) { + struct pa_autoload_entry *e; + assert(c && index != PA_IDXSET_INVALID); + + if (!c->autoload_idxset || !(e = pa_idxset_get_by_index(c->autoload_idxset, index))) + return -1; + + entry_remove_and_free(e); return 0; } @@ -117,12 +143,38 @@ void pa_autoload_request(struct pa_core *c, const char *name, enum pa_namereg_ty static void free_func(void *p, void *userdata) { struct pa_autoload_entry *e = p; + pa_idxset_remove_by_data(e->core->autoload_idxset, e, NULL); entry_free(e); } void pa_autoload_free(struct pa_core *c) { - if (!c->autoload_hashmap) - return; + if (c->autoload_hashmap) { + pa_hashmap_free(c->autoload_hashmap, free_func, NULL); + c->autoload_hashmap = NULL; + } + + if (c->autoload_idxset) { + pa_idxset_free(c->autoload_idxset, NULL, NULL); + c->autoload_idxset = NULL; + } +} + +const struct pa_autoload_entry* pa_autoload_get_by_name(struct pa_core *c, const char*name, enum pa_namereg_type type) { + struct pa_autoload_entry *e; + assert(c && name); + + if (!c->autoload_hashmap || !(e = pa_hashmap_get(c->autoload_hashmap, name)) || e->type != type) + return NULL; - pa_hashmap_free(c->autoload_hashmap, free_func, NULL); + return e; +} + +const struct pa_autoload_entry* pa_autoload_get_by_index(struct pa_core *c, uint32_t index) { + struct pa_autoload_entry *e; + assert(c && index != PA_IDXSET_INVALID); + + if (!c->autoload_idxset || !(e = pa_idxset_get_by_index(c->autoload_idxset, index))) + return NULL; + + return e; } diff --git a/polyp/autoload.h b/polyp/autoload.h index f80b1f0d..ec7d38f1 100644 --- a/polyp/autoload.h +++ b/polyp/autoload.h @@ -26,15 +26,20 @@ struct pa_autoload_entry { struct pa_core *core; + uint32_t index; char *name; enum pa_namereg_type type; int in_action; char *module, *argument; }; -int pa_autoload_add(struct pa_core *c, const char*name, enum pa_namereg_type type, const char*module, const char *argument); +int pa_autoload_add(struct pa_core *c, const char*name, enum pa_namereg_type type, const char*module, const char *argument, uint32_t *index); void pa_autoload_free(struct pa_core *c); -int pa_autoload_remove(struct pa_core *c, const char*name, enum pa_namereg_type type); +int pa_autoload_remove_by_name(struct pa_core *c, const char*name, enum pa_namereg_type type); +int pa_autoload_remove_by_index(struct pa_core *c, uint32_t index); void pa_autoload_request(struct pa_core *c, const char *name, enum pa_namereg_type type); +const struct pa_autoload_entry* pa_autoload_get_by_name(struct pa_core *c, const char*name, enum pa_namereg_type type); +const struct pa_autoload_entry* pa_autoload_get_by_index(struct pa_core *c, uint32_t index); + #endif diff --git a/polyp/cli-command.c b/polyp/cli-command.c index 39ea9cc1..62981b4d 100644 --- a/polyp/cli-command.c +++ b/polyp/cli-command.c @@ -570,7 +570,7 @@ static int pa_cli_command_autoload_add(struct pa_core *c, struct pa_tokenizer *t return -1; } - pa_autoload_add(c, a, strstr(pa_tokenizer_get(t, 0), "sink") ? PA_NAMEREG_SINK : PA_NAMEREG_SOURCE, b, pa_tokenizer_get(t, 3)); + pa_autoload_add(c, a, strstr(pa_tokenizer_get(t, 0), "sink") ? PA_NAMEREG_SINK : PA_NAMEREG_SOURCE, b, pa_tokenizer_get(t, 3), NULL); return 0; } @@ -584,7 +584,7 @@ static int pa_cli_command_autoload_remove(struct pa_core *c, struct pa_tokenizer return -1; } - if (pa_autoload_remove(c, name, strstr(pa_tokenizer_get(t, 0), "sink") ? PA_NAMEREG_SINK : PA_NAMEREG_SOURCE) < 0) { + if (pa_autoload_remove_by_name(c, name, strstr(pa_tokenizer_get(t, 0), "sink") ? PA_NAMEREG_SINK : PA_NAMEREG_SOURCE) < 0) { pa_strbuf_puts(buf, "Failed to remove autload entry\n"); return -1; } diff --git a/polyp/cli-text.c b/polyp/cli-text.c index f9bc6c7a..c08b0d9c 100644 --- a/polyp/cli-text.c +++ b/polyp/cli-text.c @@ -243,7 +243,7 @@ char *pa_scache_list_to_string(struct pa_core *c) { } pa_strbuf_printf( - s, " name: <%s>\n\tindex: <%i>\n\tsample_spec: <%s>\n\tlength: <%u>\n\tduration: <%0.1fs>\n\tvolume: <0x%04x>\n\tlazy: %s\n\tfilename: %s\n", + s, " name: <%s>\n\tindex: <%u>\n\tsample_spec: <%s>\n\tlength: <%u>\n\tduration: <%0.1fs>\n\tvolume: <0x%04x>\n\tlazy: %s\n\tfilename: %s\n", e->name, e->index, ss, @@ -273,9 +273,10 @@ char *pa_autoload_list_to_string(struct pa_core *c) { while ((e = pa_hashmap_iterate(c->autoload_hashmap, &state))) { pa_strbuf_printf( - s, " name: <%s>\n\ttype: <%s>\n\tmodule_name: <%s>\n\targuments: <%s>\n", + 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); diff --git a/polyp/core.c b/polyp/core.c index cf2d383c..c53d2e4e 100644 --- a/polyp/core.c +++ b/polyp/core.c @@ -56,7 +56,7 @@ struct pa_core* pa_core_new(struct pa_mainloop_api *m) { c->modules = NULL; c->namereg = NULL; c->scache = NULL; - + c->autoload_idxset = NULL; c->autoload_hashmap = NULL; c->default_sample_spec.format = PA_SAMPLE_S16NE; diff --git a/polyp/core.h b/polyp/core.h index 62959d0a..c457c3fd 100644 --- a/polyp/core.h +++ b/polyp/core.h @@ -31,7 +31,7 @@ struct pa_core { struct pa_mainloop_api *mainloop; - struct pa_idxset *clients, *sinks, *sources, *sink_inputs, *source_outputs, *modules, *scache; + struct pa_idxset *clients, *sinks, *sources, *sink_inputs, *source_outputs, *modules, *scache, *autoload_idxset; struct pa_hashmap *namereg, *autoload_hashmap; diff --git a/polyp/pactl.c b/polyp/pactl.c index fbedc6fa..29c06f91 100644 --- a/polyp/pactl.c +++ b/polyp/pactl.c @@ -437,11 +437,12 @@ static void get_autoload_info_callback(struct pa_context *c, const struct pa_aut printf("\n"); nl = 1; - printf("*** Autoload Entry ***\n" + printf("*** Autoload Entry #%u ***\n" "Name: %s\n" "Type: %s\n" "Module: %s\n" "Argument: %s\n", + i->index, i->name, i->type == PA_AUTOLOAD_SINK ? "sink" : "source", i->module, diff --git a/polyp/polyplib-introspect.c b/polyp/polyplib-introspect.c index 267af95b..af5fd168 100644 --- a/polyp/polyplib-introspect.c +++ b/polyp/polyplib-introspect.c @@ -823,7 +823,8 @@ static void context_get_autoload_info_callback(struct pa_pdispatch *pd, uint32_t while (!pa_tagstruct_eof(t)) { struct pa_autoload_info i; - if (pa_tagstruct_gets(t, &i.name) < 0 || + if (pa_tagstruct_getu32(t, &i.index) < 0 || + pa_tagstruct_gets(t, &i.name) < 0 || pa_tagstruct_getu32(t, &i.type) < 0 || pa_tagstruct_gets(t, &i.module) < 0 || pa_tagstruct_gets(t, &i.argument) < 0) { @@ -848,7 +849,7 @@ finish: pa_operation_unref(o); } -struct pa_operation* pa_context_get_autoload_info(struct pa_context *c, const char *name, enum pa_autoload_type type, void (*cb)(struct pa_context *c, const struct pa_autoload_info *i, int is_last, void *userdata), void *userdata) { +struct pa_operation* pa_context_get_autoload_info_by_name(struct pa_context *c, const char *name, enum pa_autoload_type type, void (*cb)(struct pa_context *c, const struct pa_autoload_info *i, int is_last, void *userdata), void *userdata) { struct pa_tagstruct *t; struct pa_operation *o; uint32_t tag; @@ -869,10 +870,58 @@ struct pa_operation* pa_context_get_autoload_info(struct pa_context *c, const ch return pa_operation_ref(o); } +struct pa_operation* pa_context_get_autoload_info_by_index(struct pa_context *c, uint32_t index, void (*cb)(struct pa_context *c, const struct pa_autoload_info *i, int is_last, void *userdata), void *userdata) { + struct pa_tagstruct *t; + struct pa_operation *o; + uint32_t tag; + assert(c && cb && index != PA_INVALID_INDEX); + + o = pa_operation_new(c, NULL); + o->callback = cb; + o->userdata = userdata; + + t = pa_tagstruct_new(NULL, 0); + pa_tagstruct_putu32(t, PA_COMMAND_GET_AUTOLOAD_INFO); + pa_tagstruct_putu32(t, tag = c->ctag++); + pa_tagstruct_putu32(t, index); + pa_pstream_send_tagstruct(c->pstream, t); + pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_autoload_info_callback, o); + + return pa_operation_ref(o); +} + struct pa_operation* pa_context_get_autoload_info_list(struct pa_context *c, void (*cb)(struct pa_context *c, const struct pa_autoload_info *i, int is_last, void *userdata), void *userdata) { return pa_context_send_simple_command(c, PA_COMMAND_GET_AUTOLOAD_INFO_LIST, context_get_autoload_info_callback, cb, userdata); } +static void context_add_autoload_callback(struct pa_pdispatch *pd, uint32_t command, uint32_t tag, struct pa_tagstruct *t, void *userdata) { + struct pa_operation *o = userdata; + uint32_t index; + assert(pd && o && o->context && o->ref >= 1); + + if (command != PA_COMMAND_REPLY) { + if (pa_context_handle_error(o->context, command, t) < 0) + goto finish; + + index = PA_INVALID_INDEX; + } else if (pa_tagstruct_getu32(t, &index) || + !pa_tagstruct_eof(t)) { + pa_context_fail(o->context, PA_ERROR_PROTOCOL); + goto finish; + } + + if (o->callback) { + void (*cb)(struct pa_context *s, uint32_t index, void *userdata) = o->callback; + cb(o->context, index, o->userdata); + } + + +finish: + pa_operation_done(o); + pa_operation_unref(o); +} + + struct pa_operation* pa_context_add_autoload(struct pa_context *c, const char *name, enum pa_autoload_type type, const char *module, const char*argument, void (*cb)(struct pa_context *c, int success, void *userdata), void* userdata) { struct pa_operation *o; struct pa_tagstruct *t; @@ -891,12 +940,12 @@ struct pa_operation* pa_context_add_autoload(struct pa_context *c, const char *n pa_tagstruct_puts(t, module); pa_tagstruct_puts(t, argument); pa_pstream_send_tagstruct(c->pstream, t); - pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, o); + pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_add_autoload_callback, o); return pa_operation_ref(o); } -struct pa_operation* pa_context_remove_autoload(struct pa_context *c, const char *name, enum pa_autoload_type type, void (*cb)(struct pa_context *c, int success, void *userdata), void* userdata) { +struct pa_operation* pa_context_remove_autoload_by_name(struct pa_context *c, const char *name, enum pa_autoload_type type, void (*cb)(struct pa_context *c, int success, void *userdata), void* userdata) { struct pa_operation *o; struct pa_tagstruct *t; uint32_t tag; @@ -916,3 +965,23 @@ struct pa_operation* pa_context_remove_autoload(struct pa_context *c, const char return pa_operation_ref(o); } + +struct pa_operation* pa_context_remove_autoload_by_index(struct pa_context *c, uint32_t index, void (*cb)(struct pa_context *c, int success, void *userdata), void* userdata) { + struct pa_operation *o; + struct pa_tagstruct *t; + uint32_t tag; + assert(c && index != PA_INVALID_INDEX); + + o = pa_operation_new(c, NULL); + o->callback = cb; + o->userdata = userdata; + + t = pa_tagstruct_new(NULL, 0); + pa_tagstruct_putu32(t, PA_COMMAND_REMOVE_AUTOLOAD); + pa_tagstruct_putu32(t, tag = c->ctag++); + pa_tagstruct_putu32(t, index); + pa_pstream_send_tagstruct(c->pstream, t); + pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, o); + + return pa_operation_ref(o); +} diff --git a/polyp/polyplib-introspect.h b/polyp/polyplib-introspect.h index 9e6c31b2..f4dbd185 100644 --- a/polyp/polyplib-introspect.h +++ b/polyp/polyplib-introspect.h @@ -234,23 +234,31 @@ enum pa_autoload_type { /** Stores information about autoload entries. \since 0.5 */ struct pa_autoload_info { + uint32_t index; /**< Index of this autoload entry */ const char *name; /**< Name of the sink or source */ enum pa_autoload_type type; /**< Type of the autoload entry */ const char *module; /**< Module name to load */ const char *argument; /**< Argument string for module */ }; -/** Get info about a specific autoload entry. \since 0.5 */ -struct pa_operation* pa_context_get_autoload_info(struct pa_context *c, const char *name, enum pa_autoload_type type, void (*cb)(struct pa_context *c, const struct pa_autoload_info *i, int is_last, void *userdata), void *userdata); +/** Get info about a specific autoload entry. \since 0.6 */ +struct pa_operation* pa_context_get_autoload_info_by_name(struct pa_context *c, const char *name, enum pa_autoload_type type, void (*cb)(struct pa_context *c, const struct pa_autoload_info *i, int is_last, void *userdata), void *userdata); + +/** Get info about a specific autoload entry. \since 0.6 */ +struct pa_operation* pa_context_get_autoload_info_by_index(struct pa_context *c, uint32_t index, void (*cb)(struct pa_context *c, const struct pa_autoload_info *i, int is_last, void *userdata), void *userdata); /** Get the complete list of autoload entries. \since 0.5 */ struct pa_operation* pa_context_get_autoload_info_list(struct pa_context *c, void (*cb)(struct pa_context *c, const struct pa_autoload_info *i, int is_last, void *userdata), void *userdata); /** Add a new autoload entry. \since 0.5 */ -struct pa_operation* pa_context_add_autoload(struct pa_context *c, const char *name, enum pa_autoload_type type, const char *module, const char*argument, void (*cb)(struct pa_context *c, int success, void *userdata), void* userdata); +struct pa_operation* pa_context_add_autoload(struct pa_context *c, const char *name, enum pa_autoload_type type, const char *module, const char*argument, void (*cb)(struct pa_context *c, int index, void *userdata), void* userdata); + +/** Remove an autoload entry. \since 0.6 */ +struct pa_operation* pa_context_remove_autoload_by_name(struct pa_context *c, const char *name, enum pa_autoload_type type, void (*cb)(struct pa_context *c, int success, void *userdata), void* userdata); + +/** Remove an autoload entry. \since 0.6 */ +struct pa_operation* pa_context_remove_autoload_by_index(struct pa_context *c, uint32_t index, void (*cb)(struct pa_context *c, int success, void *userdata), void* userdata); -/** Remove an autoload entry. \since 0.5 */ -struct pa_operation* pa_context_remove_autoload(struct pa_context *c, const char *name, enum pa_autoload_type type, void (*cb)(struct pa_context *c, int success, void *userdata), void* userdata); PA_C_DECL_END diff --git a/polyp/protocol-native.c b/polyp/protocol-native.c index 31ab4ab8..7af8bdda 100644 --- a/polyp/protocol-native.c +++ b/polyp/protocol-native.c @@ -1729,6 +1729,8 @@ static void command_add_autoload(struct pa_pdispatch *pd, uint32_t command, uint struct connection *c = userdata; const char *name, *module, *argument; uint32_t type; + uint32_t index; + struct pa_tagstruct *reply; assert(c && t); if (pa_tagstruct_gets(t, &name) < 0 || !name || @@ -1745,22 +1747,30 @@ static void command_add_autoload(struct pa_pdispatch *pd, uint32_t command, uint return; } - if (pa_autoload_add(c->protocol->core, name, type == 0 ? PA_NAMEREG_SINK : PA_NAMEREG_SOURCE, module, argument) < 0) { + if (pa_autoload_add(c->protocol->core, name, type == 0 ? PA_NAMEREG_SINK : PA_NAMEREG_SOURCE, module, argument, &index) < 0) { pa_pstream_send_error(c->pstream, tag, PA_ERROR_EXIST); return; } - pa_pstream_send_simple_ack(c->pstream, tag); + reply = pa_tagstruct_new(NULL, 0); + pa_tagstruct_putu32(reply, PA_COMMAND_REPLY); + pa_tagstruct_putu32(reply, tag); + pa_tagstruct_putu32(reply, index); + pa_pstream_send_tagstruct(c->pstream, reply); } static void command_remove_autoload(struct pa_pdispatch *pd, uint32_t command, uint32_t tag, struct pa_tagstruct *t, void *userdata) { struct connection *c = userdata; - const char *name; - uint32_t type; + const char *name = NULL; + uint32_t type, index = PA_IDXSET_INVALID; + int r; assert(c && t); - if (pa_tagstruct_gets(t, &name) < 0 || !name || - pa_tagstruct_getu32(t, &type) < 0 || type > 1 || + if ((pa_tagstruct_getu32(t, &index) < 0 && + (pa_tagstruct_gets(t, &name) < 0 || + pa_tagstruct_getu32(t, &type) < 0)) || + (!name && index == PA_IDXSET_INVALID) || + (name && type > 1) || !pa_tagstruct_eof(t)) { protocol_error(c); return; @@ -1771,7 +1781,12 @@ static void command_remove_autoload(struct pa_pdispatch *pd, uint32_t command, u return; } - if (pa_autoload_remove(c->protocol->core, name, type == 0 ? PA_NAMEREG_SINK : PA_NAMEREG_SOURCE) < 0) { + if (name) + r = pa_autoload_remove_by_name(c->protocol->core, name, type == 0 ? PA_NAMEREG_SINK : PA_NAMEREG_SOURCE); + else + r = pa_autoload_remove_by_index(c->protocol->core, index); + + if (r < 0) { pa_pstream_send_error(c->pstream, tag, PA_ERROR_NOENTITY); return; } @@ -1779,8 +1794,10 @@ static void command_remove_autoload(struct pa_pdispatch *pd, uint32_t command, u pa_pstream_send_simple_ack(c->pstream, tag); } -static void autoload_fill_tagstruct(struct pa_tagstruct *t, struct pa_autoload_entry *e) { +static void autoload_fill_tagstruct(struct pa_tagstruct *t, const struct pa_autoload_entry *e) { assert(t && e); + + pa_tagstruct_putu32(t, e->index); pa_tagstruct_puts(t, e->name); pa_tagstruct_putu32(t, e->type == PA_NAMEREG_SINK ? 0 : 1); pa_tagstruct_puts(t, e->module); @@ -1789,14 +1806,17 @@ static void autoload_fill_tagstruct(struct pa_tagstruct *t, struct pa_autoload_e static void command_get_autoload_info(struct pa_pdispatch *pd, uint32_t command, uint32_t tag, struct pa_tagstruct *t, void *userdata) { struct connection *c = userdata; - struct pa_autoload_entry *a = NULL; - uint32_t type; + const struct pa_autoload_entry *a = NULL; + uint32_t type, index; const char *name; struct pa_tagstruct *reply; assert(c && t); - - if (pa_tagstruct_gets(t, &name) < 0 || name || - pa_tagstruct_getu32(t, &type) < 0 || type > 1 || + + if ((pa_tagstruct_getu32(t, &index) < 0 && + (pa_tagstruct_gets(t, &name) < 0 || + pa_tagstruct_getu32(t, &type) < 0)) || + (!name && index == PA_IDXSET_INVALID) || + (name && type > 1) || !pa_tagstruct_eof(t)) { protocol_error(c); return; @@ -1807,7 +1827,13 @@ static void command_get_autoload_info(struct pa_pdispatch *pd, uint32_t command, return; } - if (!c->protocol->core->autoload_hashmap || !(a = pa_hashmap_get(c->protocol->core->autoload_hashmap, name)) || (a->type == PA_NAMEREG_SINK && type != 0) || (a->type == PA_NAMEREG_SOURCE && type != 1)) { + + if (name) + a = pa_autoload_get_by_name(c->protocol->core, name, type == 0 ? PA_NAMEREG_SINK : PA_NAMEREG_SOURCE); + else + a = pa_autoload_get_by_index(c->protocol->core, index); + + if (!a) { pa_pstream_send_error(c->pstream, tag, PA_ERROR_NOENTITY); return; } -- cgit