[pulseaudio-commits] 8 commits - src/modules src/pulsecore

David Henningsson diwic at kemper.freedesktop.org
Thu May 21 02:05:04 PDT 2015


 src/modules/dbus/iface-core.c           |  164 +++++++++++++++++++-------------
 src/modules/dbus/iface-module.c         |   41 +++-----
 src/modules/dbus/iface-sample.c         |   41 +++-----
 src/modules/dbus/module-dbus-protocol.c |    5 
 src/pulsecore/core-scache.c             |   16 ++-
 src/pulsecore/core.h                    |    6 +
 src/pulsecore/module.c                  |    4 
 7 files changed, 162 insertions(+), 115 deletions(-)

New commits:
commit 2a33abb1560688108bea9a479ba7619feb163b7a
Author: Juho Hämäläinen <juho.hamalainen at tieto.com>
Date:   Thu Mar 19 13:50:59 2015 +0200

    Revert "Warn on loading module-dbus-protocol"
    
    This reverts commit e2a433b222e2d4b6e85062b979e8ed3dae113aca.
    
    Events are now handled using hooks instead of asynchronous subscription
    system.

diff --git a/src/modules/dbus/module-dbus-protocol.c b/src/modules/dbus/module-dbus-protocol.c
index 53b90f5..8079d6b 100644
--- a/src/modules/dbus/module-dbus-protocol.c
+++ b/src/modules/dbus/module-dbus-protocol.c
@@ -527,11 +527,6 @@ int pa__init(pa_module *m) {
 
     pa_assert(m);
 
-    pa_log_warn("module-dbus-protocol is currently unsupported, and can sometimes cause PulseAudio crashes.");
-    pa_log_warn("The most popular use cases for module-dbus-protocol are related to changing "
-                "equalizer settings and LADSPA plugin parameters at runtime.");
-    pa_log_warn("If you don't use such functionality, it's possible that you don't actually need this module.");
-
     if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
         pa_log("Failed to parse module arguments.");
         goto fail;

commit 43f5a00fcb16f5fb04e6aa5a59efdad3ae566804
Author: Juho Hämäläinen <juho.hamalainen at tieto.com>
Date:   Thu Mar 19 13:50:58 2015 +0200

    dbus: Use hooks for module proplist changes

diff --git a/src/modules/dbus/iface-module.c b/src/modules/dbus/iface-module.c
index 95a465c..222cd73 100644
--- a/src/modules/dbus/iface-module.c
+++ b/src/modules/dbus/iface-module.c
@@ -36,7 +36,7 @@ struct pa_dbusiface_module {
     pa_proplist *proplist;
 
     pa_dbus_protocol *dbus_protocol;
-    pa_subscription *subscription;
+    pa_hook_slot *module_proplist_changed_slot;
 };
 
 static void handle_get_index(DBusConnection *conn, DBusMessage *msg, void *userdata);
@@ -264,37 +264,33 @@ static void handle_unload(DBusConnection *conn, DBusMessage *msg, void *userdata
     pa_dbus_send_empty_reply(conn, msg);
 }
 
-static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint32_t idx, void *userdata) {
-    pa_dbusiface_module *m = userdata;
-    DBusMessage *signal_msg = NULL;
-
-    pa_assert(core);
-    pa_assert((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_MODULE);
-    pa_assert(m);
+static pa_hook_result_t module_proplist_changed_cb(void *hook_data, void *call_data, void *slot_data) {
+    pa_dbusiface_module *module_iface = slot_data;
+    pa_module * module = call_data;
+    DBusMessage *signal_msg;
 
-    /* We can't use idx != m->module->index, because the m->module pointer may
-     * be stale at this point. */
-    if (pa_idxset_get_by_index(core->modules, idx) != m->module)
-        return;
+    pa_assert(module_iface);
+    pa_assert(module);
 
-    if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) != PA_SUBSCRIPTION_EVENT_CHANGE)
-        return;
+    if (module_iface->module != module)
+        return PA_HOOK_OK;
 
-    if (!pa_proplist_equal(m->proplist, m->module->proplist)) {
+    if (!pa_proplist_equal(module_iface->proplist, module->proplist)) {
         DBusMessageIter msg_iter;
 
-        pa_proplist_update(m->proplist, PA_UPDATE_SET, m->module->proplist);
+        pa_proplist_update(module_iface->proplist, PA_UPDATE_SET, module->proplist);
 
-        pa_assert_se(signal_msg = dbus_message_new_signal(m->path,
+        pa_assert_se(signal_msg = dbus_message_new_signal(module_iface->path,
                                                           PA_DBUSIFACE_MODULE_INTERFACE,
                                                           signals[SIGNAL_PROPERTY_LIST_UPDATED].name));
         dbus_message_iter_init_append(signal_msg, &msg_iter);
-        pa_dbus_append_proplist(&msg_iter, m->proplist);
+        pa_dbus_append_proplist(&msg_iter, module_iface->proplist);
 
-        pa_dbus_protocol_send_signal(m->dbus_protocol, signal_msg);
+        pa_dbus_protocol_send_signal(module_iface->dbus_protocol, signal_msg);
         dbus_message_unref(signal_msg);
-        signal_msg = NULL;
     }
+
+    return PA_HOOK_OK;
 }
 
 pa_dbusiface_module *pa_dbusiface_module_new(pa_module *module) {
@@ -307,7 +303,8 @@ pa_dbusiface_module *pa_dbusiface_module_new(pa_module *module) {
     m->path = pa_sprintf_malloc("%s/%s%u", PA_DBUS_CORE_OBJECT_PATH, OBJECT_NAME, module->index);
     m->proplist = pa_proplist_copy(module->proplist);
     m->dbus_protocol = pa_dbus_protocol_get(module->core);
-    m->subscription = pa_subscription_new(module->core, PA_SUBSCRIPTION_MASK_MODULE, subscription_cb, m);
+    m->module_proplist_changed_slot = pa_hook_connect(&module->core->hooks[PA_CORE_HOOK_MODULE_PROPLIST_CHANGED],
+                                                      PA_HOOK_NORMAL, module_proplist_changed_cb, m);
 
     pa_assert_se(pa_dbus_protocol_add_interface(m->dbus_protocol, m->path, &module_interface_info, m) >= 0);
 
@@ -321,7 +318,7 @@ void pa_dbusiface_module_free(pa_dbusiface_module *m) {
 
     pa_proplist_free(m->proplist);
     pa_dbus_protocol_unref(m->dbus_protocol);
-    pa_subscription_free(m->subscription);
+    pa_hook_slot_free(m->module_proplist_changed_slot);
 
     pa_xfree(m->path);
     pa_xfree(m);

commit ae415b07a07c9fe70714d01c91980edb25d966de
Author: Juho Hämäläinen <juho.hamalainen at tieto.com>
Date:   Thu Mar 19 13:50:57 2015 +0200

    dbus: Use hooks for module new and removed events

diff --git a/src/modules/dbus/iface-core.c b/src/modules/dbus/iface-core.c
index 083afe1..d29c70a 100644
--- a/src/modules/dbus/iface-core.c
+++ b/src/modules/dbus/iface-core.c
@@ -91,7 +91,6 @@ static void handle_stop_listening_for_signal(DBusConnection *conn, DBusMessage *
 
 struct pa_dbusiface_core {
     pa_core *core;
-    pa_subscription *subscription;
 
     pa_dbus_protocol *dbus_protocol;
 
@@ -109,6 +108,8 @@ struct pa_dbusiface_core {
     pa_sink *fallback_sink;
     pa_source *fallback_source;
 
+    pa_hook_slot *module_new_slot;
+    pa_hook_slot *module_removed_slot;
     pa_hook_slot *default_sink_changed_slot;
     pa_hook_slot *default_source_changed_slot;
     pa_hook_slot *sample_cache_new_slot;
@@ -1578,54 +1579,59 @@ static void handle_stop_listening_for_signal(DBusConnection *conn, DBusMessage *
     pa_dbus_send_empty_reply(conn, msg);
 }
 
-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_module *module_iface = NULL;
+static pa_hook_result_t module_new_cb(void *hook_data, void *call_data, void *slot_data) {
+    pa_dbusiface_core *c = slot_data;
+    pa_module * module = call_data;
+    pa_dbusiface_module *module_iface;
+    const char *object_path;
     DBusMessage *signal_msg = NULL;
-    const char *object_path = NULL;
 
     pa_assert(c);
+    pa_assert(module);
 
-    switch (t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) {
-        case PA_SUBSCRIPTION_EVENT_MODULE:
-            if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) {
-                pa_module *module = NULL;
+    if (!(module_iface = pa_hashmap_get(c->modules, PA_UINT32_TO_PTR(module->index)))) {
+        module_iface = pa_dbusiface_module_new(module);
+        pa_assert_se(pa_hashmap_put(c->modules, PA_UINT32_TO_PTR(module->index), module_iface) >= 0);
 
-                if (!(module = pa_idxset_get_by_index(core->modules, idx)))
-                    return; /* The module was removed immediately after creation. */
+        object_path = pa_dbusiface_module_get_path(module_iface);
 
-                if (!(module_iface = pa_hashmap_get(c->modules, PA_UINT32_TO_PTR(idx)))) {
-                    module_iface = pa_dbusiface_module_new(module);
-                    pa_hashmap_put(c->modules, PA_UINT32_TO_PTR(idx), module_iface);
-                }
+        pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
+                                                           PA_DBUS_CORE_INTERFACE,
+                                                           signals[SIGNAL_NEW_MODULE].name)));
+        pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
 
-                object_path = pa_dbusiface_module_get_path(module_iface);
+        pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg);
+        dbus_message_unref(signal_msg);
+    }
 
-                pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
-                                                                   PA_DBUS_CORE_INTERFACE,
-                                                                   signals[SIGNAL_NEW_MODULE].name)));
-                pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
+    return PA_HOOK_OK;
+}
 
-            } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) {
-                if (!(module_iface = pa_hashmap_remove(c->modules, PA_UINT32_TO_PTR(idx))))
-                    return;
+static pa_hook_result_t module_removed_cb(void *hook_data, void *call_data, void *slot_data) {
+    pa_dbusiface_core *c = slot_data;
+    pa_module * module = call_data;
+    pa_dbusiface_module *module_iface;
+    const char *object_path;
+    DBusMessage *signal_msg = NULL;
 
-                object_path = pa_dbusiface_module_get_path(module_iface);
+    pa_assert(c);
+    pa_assert(module);
 
-                pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
-                                                                   PA_DBUS_CORE_INTERFACE,
-                                                                   signals[SIGNAL_MODULE_REMOVED].name)));
-                pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
+    pa_assert_se((module_iface = pa_hashmap_remove(c->modules, PA_UINT32_TO_PTR(module->index))));
 
-                pa_dbusiface_module_free(module_iface);
-            }
-            break;
-    }
+    object_path = pa_dbusiface_module_get_path(module_iface);
 
-    if (signal_msg) {
-        pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg);
-        dbus_message_unref(signal_msg);
-    }
+    pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
+                                                       PA_DBUS_CORE_INTERFACE,
+                                                       signals[SIGNAL_MODULE_REMOVED].name)));
+    pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
+
+    pa_dbusiface_module_free(module_iface);
+
+    pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg);
+    dbus_message_unref(signal_msg);
+
+    return PA_HOOK_OK;
 }
 
 static pa_hook_result_t sample_cache_new_cb(void *hook_data, void *call_data, void *slot_data) {
@@ -2132,7 +2138,6 @@ pa_dbusiface_core *pa_dbusiface_core_new(pa_core *core) {
 
     c = pa_xnew(pa_dbusiface_core, 1);
     c->core = core;
-    c->subscription = pa_subscription_new(core, PA_SUBSCRIPTION_MASK_ALL, subscription_cb, c);
     c->dbus_protocol = pa_dbus_protocol_get(core);
     c->cards = pa_hashmap_new_full(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func, NULL, (pa_free_cb_t) pa_dbusiface_card_free);
     c->sinks_by_index = pa_hashmap_new_full(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func, NULL,
@@ -2154,6 +2159,10 @@ pa_dbusiface_core *pa_dbusiface_core_new(pa_core *core) {
                                                    PA_HOOK_NORMAL, default_sink_changed_cb, c);
     c->default_source_changed_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_DEFAULT_SOURCE_CHANGED],
                                                      PA_HOOK_NORMAL, default_source_changed_cb, c);
+    c->module_new_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_MODULE_NEW],
+                                         PA_HOOK_NORMAL, module_new_cb, c);
+    c->module_removed_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_MODULE_UNLINK],
+                                             PA_HOOK_NORMAL, module_removed_cb, c);
     c->sample_cache_new_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_SAMPLE_CACHE_NEW],
                                                PA_HOOK_NORMAL, sample_cache_new_cb, c);
     c->sample_cache_removed_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_SAMPLE_CACHE_UNLINK],
@@ -2237,7 +2246,6 @@ void pa_dbusiface_core_free(pa_dbusiface_core *c) {
 
     /* Note that the order of freeing is important below.
      * Do not change it for the sake of tidiness without checking! */
-    pa_subscription_free(c->subscription);
     pa_hashmap_free(c->cards);
     pa_hashmap_free(c->sinks_by_path);
     pa_hashmap_free(c->sinks_by_index);
@@ -2248,6 +2256,8 @@ void pa_dbusiface_core_free(pa_dbusiface_core *c) {
     pa_hashmap_free(c->samples);
     pa_hashmap_free(c->modules);
     pa_hashmap_free(c->clients);
+    pa_hook_slot_free(c->module_new_slot);
+    pa_hook_slot_free(c->module_removed_slot);
     pa_hook_slot_free(c->default_sink_changed_slot);
     pa_hook_slot_free(c->default_source_changed_slot);
     pa_hook_slot_free(c->sample_cache_new_slot);

commit 7e0d0b8b004a7ac350e4b62c183408d8961c12c1
Author: Juho Hämäläinen <juho.hamalainen at tieto.com>
Date:   Thu Mar 19 13:50:56 2015 +0200

    dbus: Use hook for sample cache proplist changes

diff --git a/src/modules/dbus/iface-sample.c b/src/modules/dbus/iface-sample.c
index 319c18e..61f2ba0 100644
--- a/src/modules/dbus/iface-sample.c
+++ b/src/modules/dbus/iface-sample.c
@@ -37,8 +37,9 @@ struct pa_dbusiface_sample {
     char *path;
     pa_proplist *proplist;
 
+    pa_hook_slot *sample_cache_changed_slot;
+
     pa_dbus_protocol *dbus_protocol;
-    pa_subscription *subscription;
 };
 
 static void handle_get_index(DBusConnection *conn, DBusMessage *msg, void *userdata);
@@ -446,36 +447,33 @@ static void handle_remove(DBusConnection *conn, DBusMessage *msg, void *userdata
     pa_dbus_send_empty_reply(conn, msg);
 }
 
-static void subscription_cb(pa_core *c, pa_subscription_event_type_t t, uint32_t idx, void *userdata) {
-    pa_dbusiface_sample *s = userdata;
-    DBusMessage *signal_msg = NULL;
-
-    pa_assert(c);
-    pa_assert(s);
+static pa_hook_result_t sample_cache_changed_cb(void *hook_data, void *call_data, void *slot_data) {
+    pa_dbusiface_sample *sample_iface = slot_data;
+    pa_scache_entry *sample = call_data;
+    DBusMessage *signal_msg;
 
-    /* We can't use idx != s->sample->index, because the s->sample pointer may
-     * be stale at this point. */
-    if (pa_idxset_get_by_index(c->scache, idx) != s->sample)
-        return;
+    pa_assert(sample);
+    pa_assert(sample_iface);
 
-    if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) != PA_SUBSCRIPTION_EVENT_CHANGE)
-        return;
+    if (sample_iface->sample != sample)
+        return PA_HOOK_OK;
 
-    if (!pa_proplist_equal(s->proplist, s->sample->proplist)) {
+    if (!pa_proplist_equal(sample_iface->proplist, sample_iface->sample->proplist)) {
         DBusMessageIter msg_iter;
 
-        pa_proplist_update(s->proplist, PA_UPDATE_SET, s->sample->proplist);
+        pa_proplist_update(sample_iface->proplist, PA_UPDATE_SET, sample_iface->sample->proplist);
 
-        pa_assert_se(signal_msg = dbus_message_new_signal(s->path,
+        pa_assert_se(signal_msg = dbus_message_new_signal(sample_iface->path,
                                                           PA_DBUSIFACE_SAMPLE_INTERFACE,
                                                           signals[SIGNAL_PROPERTY_LIST_UPDATED].name));
         dbus_message_iter_init_append(signal_msg, &msg_iter);
-        pa_dbus_append_proplist(&msg_iter, s->proplist);
+        pa_dbus_append_proplist(&msg_iter, sample_iface->proplist);
 
-        pa_dbus_protocol_send_signal(s->dbus_protocol, signal_msg);
+        pa_dbus_protocol_send_signal(sample_iface->dbus_protocol, signal_msg);
         dbus_message_unref(signal_msg);
-        signal_msg = NULL;
     }
+
+    return PA_HOOK_OK;
 }
 
 pa_dbusiface_sample *pa_dbusiface_sample_new(pa_dbusiface_core *core, pa_scache_entry *sample) {
@@ -490,7 +488,8 @@ pa_dbusiface_sample *pa_dbusiface_sample_new(pa_dbusiface_core *core, pa_scache_
     s->path = pa_sprintf_malloc("%s/%s%u", PA_DBUS_CORE_OBJECT_PATH, OBJECT_NAME, sample->index);
     s->proplist = pa_proplist_copy(sample->proplist);
     s->dbus_protocol = pa_dbus_protocol_get(sample->core);
-    s->subscription = pa_subscription_new(sample->core, PA_SUBSCRIPTION_MASK_SAMPLE_CACHE, subscription_cb, s);
+    s->sample_cache_changed_slot = pa_hook_connect(&sample->core->hooks[PA_CORE_HOOK_SAMPLE_CACHE_CHANGED],
+                                                   PA_HOOK_NORMAL, sample_cache_changed_cb, s);
 
     pa_assert_se(pa_dbus_protocol_add_interface(s->dbus_protocol, s->path, &sample_interface_info, s) >= 0);
 
@@ -502,9 +501,9 @@ void pa_dbusiface_sample_free(pa_dbusiface_sample *s) {
 
     pa_assert_se(pa_dbus_protocol_remove_interface(s->dbus_protocol, s->path, sample_interface_info.name) >= 0);
 
+    pa_hook_slot_free(s->sample_cache_changed_slot);
     pa_proplist_free(s->proplist);
     pa_dbus_protocol_unref(s->dbus_protocol);
-    pa_subscription_free(s->subscription);
 
     pa_xfree(s->path);
     pa_xfree(s);

commit 4e8a62c3c20fedee523b738e5d33bb2c694d8cf3
Author: Juho Hämäläinen <juho.hamalainen at tieto.com>
Date:   Thu Mar 19 13:50:55 2015 +0200

    dbus: Use hooks for sample cache new and removed events

diff --git a/src/modules/dbus/iface-core.c b/src/modules/dbus/iface-core.c
index 41a75b1..083afe1 100644
--- a/src/modules/dbus/iface-core.c
+++ b/src/modules/dbus/iface-core.c
@@ -111,6 +111,8 @@ struct pa_dbusiface_core {
 
     pa_hook_slot *default_sink_changed_slot;
     pa_hook_slot *default_source_changed_slot;
+    pa_hook_slot *sample_cache_new_slot;
+    pa_hook_slot *sample_cache_removed_slot;
     pa_hook_slot *card_put_slot;
     pa_hook_slot *card_unlink_slot;
     pa_hook_slot *sink_input_put_slot;
@@ -1578,7 +1580,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_sample *sample_iface = NULL;
     pa_dbusiface_module *module_iface = NULL;
     DBusMessage *signal_msg = NULL;
     const char *object_path = NULL;
@@ -1586,40 +1587,6 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3
     pa_assert(c);
 
     switch (t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) {
-        case PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE:
-            if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) {
-                pa_scache_entry *sample = NULL;
-
-                if (!(sample = pa_idxset_get_by_index(core->scache, idx)))
-                    return; /* The sample was removed immediately after creation. */
-
-                if (!(sample_iface = pa_hashmap_get(c->samples, PA_UINT32_TO_PTR(idx)))) {
-                    sample_iface = pa_dbusiface_sample_new(c, sample);
-                    pa_hashmap_put(c->samples, PA_UINT32_TO_PTR(idx), sample_iface);
-                }
-
-                object_path = pa_dbusiface_sample_get_path(sample_iface);
-
-                pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
-                                                                   PA_DBUS_CORE_INTERFACE,
-                                                                   signals[SIGNAL_NEW_SAMPLE].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 (!(sample_iface = pa_hashmap_remove(c->samples, PA_UINT32_TO_PTR(idx))))
-                    return;
-
-                object_path = pa_dbusiface_sample_get_path(sample_iface);
-
-                pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
-                                                                   PA_DBUS_CORE_INTERFACE,
-                                                                   signals[SIGNAL_SAMPLE_REMOVED].name)));
-                pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
-
-                pa_dbusiface_sample_free(sample_iface);
-            }
-            break;
-
         case PA_SUBSCRIPTION_EVENT_MODULE:
             if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) {
                 pa_module *module = NULL;
@@ -1661,6 +1628,59 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3
     }
 }
 
+static pa_hook_result_t sample_cache_new_cb(void *hook_data, void *call_data, void *slot_data) {
+    pa_dbusiface_core *c = slot_data;
+    pa_scache_entry *sample = call_data;
+    pa_dbusiface_sample *sample_iface;
+    const char *object_path;
+    DBusMessage *signal_msg = NULL;
+
+    pa_assert(c);
+    pa_assert(sample);
+
+    sample_iface = pa_dbusiface_sample_new(c, sample);
+    pa_assert_se(pa_hashmap_put(c->samples, PA_UINT32_TO_PTR(sample->index), sample_iface) >= 0);
+
+    object_path = pa_dbusiface_sample_get_path(sample_iface);
+
+    pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
+                                                       PA_DBUS_CORE_INTERFACE,
+                                                       signals[SIGNAL_NEW_SAMPLE].name)));
+    pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
+
+    pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg);
+    dbus_message_unref(signal_msg);
+
+    return PA_HOOK_OK;
+}
+
+static pa_hook_result_t sample_cache_removed_cb(void *hook_data, void *call_data, void *slot_data) {
+    pa_dbusiface_core *c = slot_data;
+    pa_scache_entry *sample = call_data;
+    pa_dbusiface_sample *sample_iface;
+    const char *object_path;
+    DBusMessage *signal_msg = NULL;
+
+    pa_assert(c);
+    pa_assert(sample);
+
+    pa_assert_se((sample_iface = pa_hashmap_remove(c->samples, PA_UINT32_TO_PTR(sample->index))));
+
+    object_path = pa_dbusiface_sample_get_path(sample_iface);
+
+    pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
+                                                       PA_DBUS_CORE_INTERFACE,
+                                                       signals[SIGNAL_SAMPLE_REMOVED].name)));
+    pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
+
+    pa_dbusiface_sample_free(sample_iface);
+
+    pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg);
+    dbus_message_unref(signal_msg);
+
+    return PA_HOOK_OK;
+}
+
 static pa_hook_result_t default_sink_changed_cb(void *hook_data, void *call_data, void *slot_data) {
     pa_dbusiface_core *c = slot_data;
     pa_sink *new_fallback_sink = call_data;
@@ -2134,6 +2154,10 @@ pa_dbusiface_core *pa_dbusiface_core_new(pa_core *core) {
                                                    PA_HOOK_NORMAL, default_sink_changed_cb, c);
     c->default_source_changed_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_DEFAULT_SOURCE_CHANGED],
                                                      PA_HOOK_NORMAL, default_source_changed_cb, c);
+    c->sample_cache_new_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_SAMPLE_CACHE_NEW],
+                                               PA_HOOK_NORMAL, sample_cache_new_cb, c);
+    c->sample_cache_removed_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_SAMPLE_CACHE_UNLINK],
+                                                   PA_HOOK_NORMAL, sample_cache_removed_cb, c);
     c->card_put_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_CARD_PUT],
                                        PA_HOOK_NORMAL, card_put_cb, c);
     c->card_unlink_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_CARD_UNLINK],
@@ -2226,6 +2250,8 @@ void pa_dbusiface_core_free(pa_dbusiface_core *c) {
     pa_hashmap_free(c->clients);
     pa_hook_slot_free(c->default_sink_changed_slot);
     pa_hook_slot_free(c->default_source_changed_slot);
+    pa_hook_slot_free(c->sample_cache_new_slot);
+    pa_hook_slot_free(c->sample_cache_removed_slot);
     pa_hook_slot_free(c->card_put_slot);
     pa_hook_slot_free(c->card_unlink_slot);
     pa_hook_slot_free(c->sink_input_put_slot);

commit 7a3ed4af12feb70e0291f05f505e62c45f830862
Author: Juho Hämäläinen <juho.hamalainen at tieto.com>
Date:   Thu Mar 19 13:50:54 2015 +0200

    core, core-scache: Fire hooks for new, changed and removed events
    
    (Refactored by David Henningsson)

diff --git a/src/pulsecore/core-scache.c b/src/pulsecore/core-scache.c
index 3e12b34..026eeca 100644
--- a/src/pulsecore/core-scache.c
+++ b/src/pulsecore/core-scache.c
@@ -79,6 +79,7 @@ static void free_entry(pa_scache_entry *e) {
 
     pa_namereg_unregister(e->core, e->name);
     pa_subscription_post(e->core, PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE|PA_SUBSCRIPTION_EVENT_REMOVE, e->index);
+    pa_hook_fire(&e->core->hooks[PA_CORE_HOOK_SAMPLE_CACHE_UNLINK], e);
     pa_xfree(e->name);
     pa_xfree(e->filename);
     if (e->memchunk.memblock)
@@ -88,11 +89,12 @@ static void free_entry(pa_scache_entry *e) {
     pa_xfree(e);
 }
 
-static pa_scache_entry* scache_add_item(pa_core *c, const char *name) {
+static pa_scache_entry* scache_add_item(pa_core *c, const char *name, bool *new_sample) {
     pa_scache_entry *e;
 
     pa_assert(c);
     pa_assert(name);
+    pa_assert(new_sample);
 
     if ((e = pa_namereg_get(c, name, PA_NAMEREG_SAMPLE))) {
         if (e->memchunk.memblock)
@@ -104,6 +106,7 @@ static pa_scache_entry* scache_add_item(pa_core *c, const char *name) {
         pa_assert(e->core == c);
 
         pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE|PA_SUBSCRIPTION_EVENT_CHANGE, e->index);
+        *new_sample = false;
     } else {
         e = pa_xnew(pa_scache_entry, 1);
 
@@ -119,6 +122,7 @@ static pa_scache_entry* scache_add_item(pa_core *c, const char *name) {
         pa_idxset_put(c->scache, e, &e->index);
 
         pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE|PA_SUBSCRIPTION_EVENT_NEW, e->index);
+        *new_sample = true;
     }
 
     e->last_used_time = 0;
@@ -149,6 +153,7 @@ int pa_scache_add_item(
     pa_scache_entry *e;
     char st[PA_SAMPLE_SPEC_SNPRINT_MAX];
     pa_channel_map tmap;
+    bool new_sample;
 
     pa_assert(c);
     pa_assert(name);
@@ -163,7 +168,7 @@ int pa_scache_add_item(
     if (chunk && chunk->length > PA_SCACHE_ENTRY_SIZE_MAX)
         return -1;
 
-    if (!(e = scache_add_item(c, name)))
+    if (!(e = scache_add_item(c, name, &new_sample)))
         return -1;
 
     pa_sample_spec_init(&e->sample_spec);
@@ -194,6 +199,8 @@ int pa_scache_add_item(
                  name, e->index, (unsigned long) e->memchunk.length,
                  pa_sample_spec_snprint(st, sizeof(st), &e->sample_spec));
 
+    pa_hook_fire(&e->core->hooks[new_sample ? PA_CORE_HOOK_SAMPLE_CACHE_NEW : PA_CORE_HOOK_SAMPLE_CACHE_CHANGED], e);
+
     return 0;
 }
 
@@ -232,6 +239,7 @@ int pa_scache_add_file(pa_core *c, const char *name, const char *filename, uint3
 
 int pa_scache_add_file_lazy(pa_core *c, const char *name, const char *filename, uint32_t *idx) {
     pa_scache_entry *e;
+    bool new_sample;
 
 #ifdef OS_IS_WIN32
     char buf[MAX_PATH];
@@ -244,7 +252,7 @@ int pa_scache_add_file_lazy(pa_core *c, const char *name, const char *filename,
     pa_assert(name);
     pa_assert(filename);
 
-    if (!(e = scache_add_item(c, name)))
+    if (!(e = scache_add_item(c, name, &new_sample)))
         return -1;
 
     e->lazy = true;
@@ -258,6 +266,8 @@ int pa_scache_add_file_lazy(pa_core *c, const char *name, const char *filename,
     if (idx)
         *idx = e->index;
 
+    pa_hook_fire(&e->core->hooks[new_sample ? PA_CORE_HOOK_SAMPLE_CACHE_NEW : PA_CORE_HOOK_SAMPLE_CACHE_CHANGED], e);
+
     return 0;
 }
 
diff --git a/src/pulsecore/core.h b/src/pulsecore/core.h
index 1d75274..6a8affc 100644
--- a/src/pulsecore/core.h
+++ b/src/pulsecore/core.h
@@ -131,6 +131,9 @@ typedef enum pa_core_hook {
     PA_CORE_HOOK_MODULE_NEW,
     PA_CORE_HOOK_MODULE_PROPLIST_CHANGED,
     PA_CORE_HOOK_MODULE_UNLINK,
+    PA_CORE_HOOK_SAMPLE_CACHE_NEW,
+    PA_CORE_HOOK_SAMPLE_CACHE_CHANGED,
+    PA_CORE_HOOK_SAMPLE_CACHE_UNLINK,
     PA_CORE_HOOK_MAX
 } pa_core_hook_t;
 

commit e0b89669542021841f8898595b6b20c64cc7f816
Author: Juho Hämäläinen <juho.hamalainen at tieto.com>
Date:   Thu Mar 19 13:50:52 2015 +0200

    module: Fire hooks for new, proplist changed and removed
    
    (Unlink callback moved by David Henningsson)

diff --git a/src/pulsecore/module.c b/src/pulsecore/module.c
index 256d4de..8683cc1 100644
--- a/src/pulsecore/module.c
+++ b/src/pulsecore/module.c
@@ -200,6 +200,8 @@ pa_module* pa_module_load(pa_core *c, const char *name, const char *argument) {
         pa_modinfo_free(mi);
     }
 
+    pa_hook_fire(&m->core->hooks[PA_CORE_HOOK_MODULE_NEW], m);
+
     return m;
 
 fail:
@@ -231,6 +233,7 @@ static void pa_module_free(pa_module *m) {
     pa_assert(m->core);
 
     pa_log_info("Unloading \"%s\" (index: #%u).", m->name, m->index);
+    pa_hook_fire(&m->core->hooks[PA_CORE_HOOK_MODULE_UNLINK], m);
 
     if (m->hooks) {
        pa_dynarray_free(m->hooks);
@@ -370,4 +373,5 @@ void pa_module_update_proplist(pa_module *m, pa_update_mode_t mode, pa_proplist
         pa_proplist_update(m->proplist, mode, p);
 
     pa_subscription_post(m->core, PA_SUBSCRIPTION_EVENT_MODULE|PA_SUBSCRIPTION_EVENT_CHANGE, m->index);
+    pa_hook_fire(&m->core->hooks[PA_CORE_HOOK_MODULE_PROPLIST_CHANGED], m);
 }

commit f5340b90d95bc0aaa2e6ff3831053cb05f7c833d
Author: Juho Hämäläinen <juho.hamalainen at tieto.com>
Date:   Thu Mar 19 13:50:51 2015 +0200

    core: Add core hooks for module changes
    
    (Name adjusted by David Henningsson)

diff --git a/src/pulsecore/core.h b/src/pulsecore/core.h
index 9fefd1b..1d75274 100644
--- a/src/pulsecore/core.h
+++ b/src/pulsecore/core.h
@@ -128,6 +128,9 @@ typedef enum pa_core_hook {
     PA_CORE_HOOK_PORT_LATENCY_OFFSET_CHANGED,
     PA_CORE_HOOK_DEFAULT_SINK_CHANGED,
     PA_CORE_HOOK_DEFAULT_SOURCE_CHANGED,
+    PA_CORE_HOOK_MODULE_NEW,
+    PA_CORE_HOOK_MODULE_PROPLIST_CHANGED,
+    PA_CORE_HOOK_MODULE_UNLINK,
     PA_CORE_HOOK_MAX
 } pa_core_hook_t;
 



More information about the pulseaudio-commits mailing list