[pulseaudio-discuss] [PATCH] pactl: Added unloading modules by name
poljar
poljarinho at gmail.com
Wed May 16 13:39:12 PDT 2012
pactl should allow unloading modules by name.
pactl and the native protocol were expanded to handle names while
unloading modules.
BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=48289
---
src/map-file | 3 ++-
src/pulse/introspect.c | 46 +++++++++++++++++++++++++++++++++++++--
src/pulse/introspect.h | 8 +++++--
src/pulsecore/protocol-native.c | 29 ++++++++++++++++++++----
src/utils/pactl.c | 13 ++++++++---
5 files changed, 87 insertions(+), 12 deletions(-)
diff --git a/src/map-file b/src/map-file
index 69cf25b..82fdd06 100644
--- a/src/map-file
+++ b/src/map-file
@@ -113,7 +113,8 @@ pa_context_suspend_sink_by_index;
pa_context_suspend_sink_by_name;
pa_context_suspend_source_by_index;
pa_context_suspend_source_by_name;
-pa_context_unload_module;
+pa_context_unload_module_by_index;
+pa_context_unload_module_by_name;
pa_context_unref;
pa_cvolume_avg;
pa_cvolume_avg_mask;
diff --git a/src/pulse/introspect.c b/src/pulse/introspect.c
index 38a9d1c..332733b 100644
--- a/src/pulse/introspect.c
+++ b/src/pulse/introspect.c
@@ -1864,8 +1864,50 @@ pa_operation* pa_context_load_module(pa_context *c, const char*name, const char
return o;
}
-pa_operation* pa_context_unload_module(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata) {
- return command_kill(c, PA_COMMAND_UNLOAD_MODULE, idx, cb, userdata);
+pa_operation* pa_context_unload_module_by_index(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata) {
+ pa_operation *o;
+ pa_tagstruct *t;
+ uint32_t tag;
+
+ pa_assert(c);
+ pa_assert(PA_REFCNT_VALUE(c) >= 1);
+
+ PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
+ PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
+ PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
+
+ o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
+
+ t = pa_tagstruct_command(c, PA_COMMAND_UNLOAD_MODULE, &tag);
+ pa_tagstruct_putu32(t, idx);
+ pa_tagstruct_puts(t, NULL);
+ pa_pstream_send_tagstruct(c->pstream, t);
+ pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
+
+ return o;
+}
+
+pa_operation* pa_context_unload_module_by_name(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata) {
+ pa_operation *o;
+ pa_tagstruct *t;
+ uint32_t tag;
+
+ pa_assert(c);
+ pa_assert(PA_REFCNT_VALUE(c) >= 1);
+
+ PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
+ PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
+ PA_CHECK_VALIDITY_RETURN_NULL(c, name && *name, PA_ERR_INVALID);
+
+ o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
+
+ t = pa_tagstruct_command(c, PA_COMMAND_UNLOAD_MODULE, &tag);
+ pa_tagstruct_putu32(t, PA_INVALID_INDEX);
+ pa_tagstruct_puts(t, name);
+ pa_pstream_send_tagstruct(c->pstream, t);
+ pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
+
+ return o;
}
/*** Autoload stuff ***/
diff --git a/src/pulse/introspect.h b/src/pulse/introspect.h
index 0072f5d..f80fb86 100644
--- a/src/pulse/introspect.h
+++ b/src/pulse/introspect.h
@@ -409,8 +409,12 @@ typedef void (*pa_context_index_cb_t)(pa_context *c, uint32_t idx, void *userdat
/** Load a module. */
pa_operation* pa_context_load_module(pa_context *c, const char*name, const char *argument, pa_context_index_cb_t cb, void *userdata);
-/** Unload a module. */
-pa_operation* pa_context_unload_module(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata);
+/** Unload a module by its index. */
+pa_operation* pa_context_unload_module_by_index(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata);
+
+
+/** Unload a module by its name. */
+pa_operation* pa_context_unload_module_by_name(pa_context *c, const char*name, pa_context_success_cb_t cb, void *userdata);
/** @} */
diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c
index 396e143..56722e4 100644
--- a/src/pulsecore/protocol-native.c
+++ b/src/pulsecore/protocol-native.c
@@ -4434,23 +4434,44 @@ static void command_load_module(pa_pdispatch *pd, uint32_t command, uint32_t tag
static void command_unload_module(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
uint32_t idx;
+ const char *name;
pa_module *m;
pa_native_connection_assert_ref(c);
pa_assert(t);
if (pa_tagstruct_getu32(t, &idx) < 0 ||
+ pa_tagstruct_gets(t, &name) < 0 ||
!pa_tagstruct_eof(t)) {
protocol_error(c);
return;
}
CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
- m = pa_idxset_get_by_index(c->protocol->core->modules, idx);
- CHECK_VALIDITY(c->pstream, m, tag, PA_ERR_NOENTITY);
- pa_module_unload_request(m, FALSE);
- pa_pstream_send_simple_ack(c->pstream, tag);
+ if (idx != PA_INVALID_INDEX) {
+ CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX, tag, PA_ERR_INVALID);
+
+ m = pa_idxset_get_by_index(c->protocol->core->modules, idx);
+
+ CHECK_VALIDITY(c->pstream, m, tag, PA_ERR_NOENTITY);
+
+ pa_module_unload_request(m, FALSE);
+ pa_pstream_send_simple_ack(c->pstream, tag);
+ }
+ else {
+ CHECK_VALIDITY(c->pstream, name && *name && pa_utf8_valid(name) && !strchr(name, '/'), tag, PA_ERR_INVALID);
+
+ /* Traverse the module list and unload all modules with the matching name */
+ for (m = pa_idxset_first(c->protocol->core->modules, &idx); m; m = pa_idxset_next(c->protocol->core->modules, &idx)) {
+ if (strcmp(name, m->name) == 0) {
+ CHECK_VALIDITY(c->pstream, m, tag, PA_ERR_NOENTITY);
+
+ pa_module_unload_request(m, FALSE);
+ pa_pstream_send_simple_ack(c->pstream, tag);
+ }
+ }
+ }
}
static void command_move_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
diff --git a/src/utils/pactl.c b/src/utils/pactl.c
index 05a1519..b1f72f8 100644
--- a/src/utils/pactl.c
+++ b/src/utils/pactl.c
@@ -32,6 +32,7 @@
#include <stdlib.h>
#include <getopt.h>
#include <locale.h>
+#include <ctype.h>
#include <sndfile.h>
@@ -1152,7 +1153,10 @@ static void context_state_callback(pa_context *c, void *userdata) {
break;
case UNLOAD_MODULE:
- pa_operation_unref(pa_context_unload_module(c, module_index, simple_callback, NULL));
+ if (module_name)
+ pa_operation_unref(pa_context_unload_module_by_name(c, module_name, simple_callback, NULL));
+ else
+ pa_operation_unref(pa_context_unload_module_by_index(c, module_index, simple_callback, NULL));
break;
case SUSPEND_SINK:
@@ -1345,7 +1349,7 @@ static void help(const char *argv0) {
printf("%s %s %s %s\n", argv0, _("[options]"), "play-sample ", _("NAME [SINK]"));
printf("%s %s %s %s\n", argv0, _("[options]"), "remove-sample ", _("NAME"));
printf("%s %s %s %s\n", argv0, _("[options]"), "load-module ", _("NAME [ARGS ...]"));
- printf("%s %s %s %s\n", argv0, _("[options]"), "unload-module ", _("#N"));
+ printf("%s %s %s %s\n", argv0, _("[options]"), "unload-module ", _("NAME|#N"));
printf("%s %s %s %s\n", argv0, _("[options]"), "move-(sink-input|source-output)", _("#N SINK|SOURCE"));
printf("%s %s %s %s\n", argv0, _("[options]"), "suspend-(sink|source)", _("NAME|#N 1|0"));
printf("%s %s %s %s\n", argv0, _("[options]"), "set-card-profile ", _("CARD PROFILE"));
@@ -1572,7 +1576,10 @@ int main(int argc, char *argv[]) {
goto quit;
}
- module_index = (uint32_t) atoi(argv[optind+1]);
+ if (isdigit(argv[optind+1][0]))
+ module_index = (uint32_t) atoi(argv[optind+1]);
+ else
+ module_name = argv[optind+1];
} else if (pa_streq(argv[optind], "suspend-sink")) {
action = SUSPEND_SINK;
--
1.7.10.2
More information about the pulseaudio-discuss
mailing list