mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-10-29 05:40:23 -04:00
make autoload list use idxset
git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@262 fefdeb5f-60dc-0310-8127-8f9354f1896f
This commit is contained in:
parent
f252edb794
commit
1bcec3ef5b
11 changed files with 205 additions and 44 deletions
3
doc/todo
3
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
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
pa_hashmap_free(c->autoload_hashmap, free_func, NULL);
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue