[pulseaudio-discuss] [PATCH v2 3/9] dbus: Track streams with hooks

Tanu Kaskinen tanuk at iki.fi
Wed Feb 20 10:23:58 PST 2013


---
 src/modules/dbus/iface-core.c |  175 +++++++++++++++++++++++++----------------
 1 file changed, 106 insertions(+), 69 deletions(-)

diff --git a/src/modules/dbus/iface-core.c b/src/modules/dbus/iface-core.c
index 4621726..47c3c0d 100644
--- a/src/modules/dbus/iface-core.c
+++ b/src/modules/dbus/iface-core.c
@@ -114,6 +114,10 @@ struct pa_dbusiface_core {
     pa_hook_slot *sink_unlink_slot;
     pa_hook_slot *source_put_slot;
     pa_hook_slot *source_unlink_slot;
+    pa_hook_slot *sink_input_put_slot;
+    pa_hook_slot *sink_input_unlink_slot;
+    pa_hook_slot *source_output_put_slot;
+    pa_hook_slot *source_output_unlink_slot;
     pa_hook_slot *extension_registered_slot;
     pa_hook_slot *extension_unregistered_slot;
 
@@ -1557,7 +1561,6 @@ static void handle_stop_listening_for_signal(DBusConnection *conn, DBusMessage *
 static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint32_t idx, void *userdata) {
     pa_dbusiface_core *c = userdata;
     pa_dbusiface_card *card_iface = NULL;
-    pa_dbusiface_stream *stream_iface = NULL;
     pa_dbusiface_sample *sample_iface = NULL;
     pa_dbusiface_module *module_iface = NULL;
     pa_dbusiface_client *client_iface = NULL;
@@ -1602,74 +1605,6 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3
             }
             break;
 
-        case PA_SUBSCRIPTION_EVENT_SINK_INPUT:
-            if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) {
-                pa_sink_input *sink_input = NULL;
-
-                if (!(sink_input = pa_idxset_get_by_index(core->sink_inputs, idx)))
-                    return; /* The sink input was removed immediately after creation. */
-
-                if (!(stream_iface = pa_hashmap_get(c->playback_streams, PA_UINT32_TO_PTR(idx)))) {
-                    stream_iface = pa_dbusiface_stream_new_playback(c, sink_input);
-                    pa_hashmap_put(c->playback_streams, PA_UINT32_TO_PTR(idx), stream_iface);
-                }
-
-                object_path = pa_dbusiface_stream_get_path(stream_iface);
-
-                pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
-								   PA_DBUS_CORE_INTERFACE,
-								   signals[SIGNAL_NEW_PLAYBACK_STREAM].name)));
-                pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
-
-            } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) {
-                if (!(stream_iface = pa_hashmap_remove(c->playback_streams, PA_UINT32_TO_PTR(idx))))
-                    return;
-
-                object_path = pa_dbusiface_stream_get_path(stream_iface);
-
-                pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
-								   PA_DBUS_CORE_INTERFACE,
-								   signals[SIGNAL_PLAYBACK_STREAM_REMOVED].name)));
-                pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
-
-                pa_dbusiface_stream_free(stream_iface);
-            }
-            break;
-
-        case PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT:
-            if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) {
-                pa_source_output *source_output = NULL;
-
-                if (!(source_output = pa_idxset_get_by_index(core->source_outputs, idx)))
-                    return; /* The source output was removed immediately after creation. */
-
-                if (!(stream_iface = pa_hashmap_get(c->record_streams, PA_UINT32_TO_PTR(idx)))) {
-                    stream_iface = pa_dbusiface_stream_new_record(c, source_output);
-                    pa_hashmap_put(c->record_streams, PA_UINT32_TO_PTR(idx), stream_iface);
-                }
-
-                object_path = pa_dbusiface_stream_get_path(stream_iface);
-
-                pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
-								   PA_DBUS_CORE_INTERFACE,
-								   signals[SIGNAL_NEW_RECORD_STREAM].name)));
-                pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
-
-            } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) {
-                if (!(stream_iface = pa_hashmap_remove(c->record_streams, PA_UINT32_TO_PTR(idx))))
-                    return;
-
-                object_path = pa_dbusiface_stream_get_path(stream_iface);
-
-                pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
-								   PA_DBUS_CORE_INTERFACE,
-								   signals[SIGNAL_RECORD_STREAM_REMOVED].name)));
-                pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
-
-                pa_dbusiface_stream_free(stream_iface);
-            }
-            break;
-
         case PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE:
             if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) {
                 pa_scache_entry *sample = NULL;
@@ -1943,6 +1878,100 @@ static pa_hook_result_t source_unlink_cb(void *hook_data, void *call_data, void
     return PA_HOOK_OK;
 }
 
+static pa_hook_result_t sink_input_put_cb(pa_core *core, pa_sink_input *input, pa_dbusiface_core *core_iface) {
+    pa_dbusiface_stream *stream_iface = NULL;
+    const char *object_path = NULL;
+    DBusMessage *signal_msg = NULL;
+
+    pa_assert(core);
+    pa_assert(input);
+    pa_assert(core_iface);
+
+    stream_iface = pa_dbusiface_stream_new_playback(core_iface, input);
+    pa_assert_se(pa_hashmap_put(core_iface->playback_streams, PA_UINT32_TO_PTR(input->index), stream_iface) >= 0);
+
+    object_path = pa_dbusiface_stream_get_path(stream_iface);
+    pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
+                                                       PA_DBUS_CORE_INTERFACE,
+                                                       signals[SIGNAL_NEW_PLAYBACK_STREAM].name)));
+    pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
+    pa_dbus_protocol_send_signal(core_iface->dbus_protocol, signal_msg);
+    dbus_message_unref(signal_msg);
+
+    return PA_HOOK_OK;
+}
+
+static pa_hook_result_t sink_input_unlink_cb(pa_core *core, pa_sink_input *input, pa_dbusiface_core *core_iface) {
+    pa_dbusiface_stream *stream_iface = NULL;
+    const char *object_path = NULL;
+    DBusMessage *signal_msg = NULL;
+
+    pa_assert(core);
+    pa_assert(input);
+    pa_assert(core_iface);
+
+    pa_assert_se(stream_iface = pa_hashmap_remove(core_iface->playback_streams, PA_UINT32_TO_PTR(input->index)));
+
+    object_path = pa_dbusiface_stream_get_path(stream_iface);
+    pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
+                                                       PA_DBUS_CORE_INTERFACE,
+                                                       signals[SIGNAL_PLAYBACK_STREAM_REMOVED].name)));
+    pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
+    pa_dbus_protocol_send_signal(core_iface->dbus_protocol, signal_msg);
+    dbus_message_unref(signal_msg);
+
+    pa_dbusiface_stream_free(stream_iface);
+
+    return PA_HOOK_OK;
+}
+
+static pa_hook_result_t source_output_put_cb(pa_core *core, pa_source_output *output, pa_dbusiface_core *core_iface) {
+    pa_dbusiface_stream *stream_iface = NULL;
+    const char *object_path = NULL;
+    DBusMessage *signal_msg = NULL;
+
+    pa_assert(core);
+    pa_assert(output);
+    pa_assert(core_iface);
+
+    stream_iface = pa_dbusiface_stream_new_record(core_iface, output);
+    pa_assert_se(pa_hashmap_put(core_iface->record_streams, PA_UINT32_TO_PTR(output->index), stream_iface) >= 0);
+
+    object_path = pa_dbusiface_stream_get_path(stream_iface);
+    pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
+                                                       PA_DBUS_CORE_INTERFACE,
+                                                       signals[SIGNAL_NEW_RECORD_STREAM].name)));
+    pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
+    pa_dbus_protocol_send_signal(core_iface->dbus_protocol, signal_msg);
+    dbus_message_unref(signal_msg);
+
+    return PA_HOOK_OK;
+}
+
+static pa_hook_result_t source_output_unlink_cb(pa_core *core, pa_source_output *output, pa_dbusiface_core *core_iface) {
+    pa_dbusiface_stream *stream_iface = NULL;
+    const char *object_path = NULL;
+    DBusMessage *signal_msg = NULL;
+
+    pa_assert(core);
+    pa_assert(output);
+    pa_assert(core_iface);
+
+    pa_assert_se(stream_iface = pa_hashmap_remove(core_iface->record_streams, PA_UINT32_TO_PTR(output->index)));
+
+    object_path = pa_dbusiface_stream_get_path(stream_iface);
+    pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
+                                                       PA_DBUS_CORE_INTERFACE,
+                                                       signals[SIGNAL_RECORD_STREAM_REMOVED].name)));
+    pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
+    pa_dbus_protocol_send_signal(core_iface->dbus_protocol, signal_msg);
+    dbus_message_unref(signal_msg);
+
+    pa_dbusiface_stream_free(stream_iface);
+
+    return PA_HOOK_OK;
+}
+
 static pa_hook_result_t extension_registered_cb(void *hook_data, void *call_data, void *slot_data) {
     pa_dbusiface_core *c = slot_data;
     const char *ext_name = call_data;
@@ -2016,6 +2045,10 @@ pa_dbusiface_core *pa_dbusiface_core_new(pa_core *core) {
     c->sink_unlink_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_SINK_UNLINK], PA_HOOK_NORMAL, sink_unlink_cb, c);
     c->source_put_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_SOURCE_PUT], PA_HOOK_NORMAL, source_put_cb, c);
     c->source_unlink_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_SOURCE_UNLINK], PA_HOOK_NORMAL, source_unlink_cb, c);
+    c->sink_input_put_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_SINK_INPUT_PUT], PA_HOOK_NORMAL, (pa_hook_cb_t) sink_input_put_cb, c);
+    c->sink_input_unlink_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_SINK_INPUT_UNLINK], PA_HOOK_NORMAL, (pa_hook_cb_t) sink_input_unlink_cb, c);
+    c->source_output_put_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_PUT], PA_HOOK_NORMAL, (pa_hook_cb_t) source_output_put_cb, c);
+    c->source_output_unlink_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_UNLINK], PA_HOOK_NORMAL, (pa_hook_cb_t) source_output_unlink_cb, c);
     c->extension_registered_slot = pa_dbus_protocol_hook_connect(c->dbus_protocol,
                                                                  PA_DBUS_PROTOCOL_HOOK_EXTENSION_REGISTERED,
                                                                  PA_HOOK_NORMAL,
@@ -2081,6 +2114,10 @@ void pa_dbusiface_core_free(pa_dbusiface_core *c) {
     pa_hashmap_free(c->samples, (pa_free_cb_t) pa_dbusiface_sample_free);
     pa_hashmap_free(c->modules, (pa_free_cb_t) pa_dbusiface_module_free);
     pa_hashmap_free(c->clients, (pa_free_cb_t) pa_dbusiface_client_free);
+    pa_hook_slot_free(c->source_output_unlink_slot);
+    pa_hook_slot_free(c->source_output_put_slot);
+    pa_hook_slot_free(c->sink_input_unlink_slot);
+    pa_hook_slot_free(c->sink_input_put_slot);
     pa_hook_slot_free(c->sink_put_slot);
     pa_hook_slot_free(c->sink_unlink_slot);
     pa_hook_slot_free(c->source_put_slot);
-- 
1.7.10.4



More information about the pulseaudio-discuss mailing list