* [PATCH] dbus: Added l_dbus_signal_emit
@ 2019-02-01 13:41 =?unknown-8bit?q?Micha=C5=82?= 'Khorne' Lowas-Rzechonek
2019-02-01 17:39 ` Denis Kenzior
0 siblings, 1 reply; 3+ messages in thread
From: =?unknown-8bit?q?Micha=C5=82?= 'Khorne' Lowas-Rzechonek @ 2019-02-01 13:41 UTC (permalink / raw)
To: ell
[-- Attachment #1: Type: text/plain, Size: 6712 bytes --]
From: Michał Lowas-Rzechonek <michal.lowas-rzechonek@silvair.com>
After declaring a signal with l_dbus_interface_signal, we need a way to
actually publish it.
This commit adds API for this, along with an updated example.
---
ell/dbus-service.c | 98 +++++++++++++++++++++++++++++++++++++++++
ell/dbus-service.h | 4 ++
examples/dbus-service.c | 12 ++++-
3 files changed, 112 insertions(+), 2 deletions(-)
diff --git a/ell/dbus-service.c b/ell/dbus-service.c
index 531b710..428f590 100644
--- a/ell/dbus-service.c
+++ b/ell/dbus-service.c
@@ -125,12 +125,19 @@ struct property_change_record {
struct l_queue *properties;
};
+struct user_signal_record {
+ char *path;
+ struct object_node *object;
+ struct l_dbus_message *message;
+};
+
struct _dbus_object_tree {
struct l_hashmap *interfaces;
struct l_hashmap *objects;
struct object_node *root;
struct l_queue *object_managers;
struct l_queue *property_changes;
+ struct l_queue *user_signals;
struct l_idle *emit_signals_work;
bool flushing;
};
@@ -551,6 +558,15 @@ static void property_change_record_free(void *data)
l_free(rec);
}
+static void user_signal_record_free(void *data)
+{
+ struct user_signal_record *rec = data;
+
+ l_free(rec->path);
+ l_dbus_message_unref(rec->message);
+ l_free(rec);
+}
+
static void properties_setup_func(struct l_dbus_interface *);
static void object_manager_setup_func(struct l_dbus_interface *);
@@ -570,6 +586,7 @@ struct _dbus_object_tree *_dbus_object_tree_new()
tree->root = l_new(struct object_node, 1);
tree->property_changes = l_queue_new();
+ tree->user_signals = l_queue_new();
_dbus_object_tree_register_interface(tree, L_DBUS_INTERFACE_PROPERTIES,
properties_setup_func, NULL,
@@ -629,6 +646,8 @@ void _dbus_object_tree_free(struct _dbus_object_tree *tree)
l_queue_destroy(tree->property_changes, property_change_record_free);
+ l_queue_destroy(tree->user_signals, user_signal_record_free);
+
if (tree->emit_signals_work)
l_idle_remove(tree->emit_signals_work);
@@ -1100,6 +1119,22 @@ static bool emit_properties_changed(void *data, void *user_data)
return true;
}
+static bool emit_user_signal(void *data, void *user_data)
+{
+ struct user_signal_record *rec = data;
+ struct emit_signals_data *es = user_data;
+
+ if (es->node && rec->object != es->node)
+ return false;
+
+ l_dbus_send(es->dbus, rec->message);
+ rec->message = NULL;
+
+ user_signal_record_free(rec);
+
+ return true;
+}
+
void _dbus_object_tree_signals_flush(struct l_dbus *dbus, const char *path)
{
struct _dbus_object_tree *tree = _dbus_get_tree(dbus);
@@ -1138,6 +1173,12 @@ void _dbus_object_tree_signals_flush(struct l_dbus *dbus, const char *path)
if (!l_queue_isempty(tree->property_changes))
all_done = false;
+ l_queue_foreach_remove(tree->user_signals,
+ emit_user_signal, &data);
+
+ if (!l_queue_isempty(tree->user_signals))
+ all_done = false;
+
if (all_done) {
l_idle_remove(tree->emit_signals_work);
tree->emit_signals_work = NULL;
@@ -1757,6 +1798,63 @@ LIB_EXPORT bool l_dbus_property_changed(struct l_dbus *dbus, const char *path,
property);
}
+LIB_EXPORT bool l_dbus_signal_emit(struct l_dbus *dbus,
+ const char *path,
+ const char *interface_name,
+ const char *signal_name,
+ const char *signature,
+ ...)
+{
+ struct user_signal_record *rec;
+ struct object_node *object;
+ struct interface_instance *instance;
+ struct l_dbus_message_builder *builder;
+ struct _dbus_signal *signal;
+ struct _dbus_object_tree *tree = _dbus_get_tree(dbus);
+ va_list args;
+
+ object = l_hashmap_lookup(tree->objects, path);
+ if (!object)
+ return false;
+
+ instance = l_queue_find(object->instances, match_interface_instance,
+ interface_name);
+ if (!instance)
+ return false;
+
+ signal = _dbus_interface_find_signal(instance->interface,
+ signal_name);
+ if (!signal)
+ return false;
+
+ rec = l_new(struct user_signal_record, 1);
+ rec->path = l_strdup(path);
+ rec->object = object;
+ rec->message = l_dbus_message_new_signal(dbus, path,
+ interface_name, signal_name);
+
+ builder = l_dbus_message_builder_new(rec->message);
+ if (!builder) {
+ l_dbus_message_unref(rec->message);
+ l_free(rec->path);
+ l_free(rec);
+ return false;
+ }
+
+ va_start(args, signature);
+ l_dbus_message_builder_append_from_valist(builder, signature, args);
+ va_end(args);
+
+ l_dbus_message_builder_finalize(builder);
+ l_dbus_message_builder_destroy(builder);
+
+ l_queue_push_tail(tree->user_signals, rec);
+ schedule_emit_signals(dbus);
+
+ return true;
+}
+
+
static struct l_dbus_message *properties_get(struct l_dbus *dbus,
struct l_dbus_message *message,
void *user_data)
diff --git a/ell/dbus-service.h b/ell/dbus-service.h
index 153bb3a..1b442b0 100644
--- a/ell/dbus-service.h
+++ b/ell/dbus-service.h
@@ -86,6 +86,10 @@ bool l_dbus_interface_property(struct l_dbus_interface *interface,
bool l_dbus_property_changed(struct l_dbus *dbus, const char *path,
const char *interface, const char *property);
+bool l_dbus_signal_emit(struct l_dbus *dbus, const char *path,
+ const char *interface_name, const char *signal_name,
+ const char *signature, ...);
+
#ifdef __cplusplus
}
#endif
diff --git a/examples/dbus-service.c b/examples/dbus-service.c
index 280057c..e30a91d 100644
--- a/examples/dbus-service.c
+++ b/examples/dbus-service.c
@@ -87,11 +87,15 @@ static struct l_dbus_message *test_method_call(struct l_dbus *dbus,
{
struct l_dbus_message *reply;
- l_info("Method Call");
+ uint32_t argument;
+ l_dbus_message_get_arguments(message, "u", &argument);
+ l_info("Method Call: %" PRIu32 "", argument);
reply = l_dbus_message_new_method_return(message);
l_dbus_message_set_arguments(reply, "");
+ l_dbus_signal_emit(dbus, "/test", "org.test", "MethodCalled", "u", argument);
+
return reply;
}
@@ -167,10 +171,14 @@ static struct l_dbus_message *test_int_setter(struct l_dbus *dbus,
static void setup_test_interface(struct l_dbus_interface *interface)
{
l_dbus_interface_method(interface, "MethodCall", 0,
- test_method_call, "", "");
+ test_method_call, "", "u", "argument");
+
+ l_dbus_interface_signal(interface, "MethodCalled", 0,
+ "u", "argument");
l_dbus_interface_property(interface, "String", 0, "s",
test_string_getter, test_string_setter);
+
l_dbus_interface_property(interface, "Integer", 0, "u",
test_int_getter, test_int_setter);
}
--
2.19.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] dbus: Added l_dbus_signal_emit
2019-02-01 13:41 [PATCH] dbus: Added l_dbus_signal_emit =?unknown-8bit?q?Micha=C5=82?= 'Khorne' Lowas-Rzechonek
@ 2019-02-01 17:39 ` Denis Kenzior
2019-02-01 19:12 ` =?unknown-8bit?q?Micha=C5=82?= 'Khorne' Lowas-Rzechonek
0 siblings, 1 reply; 3+ messages in thread
From: Denis Kenzior @ 2019-02-01 17:39 UTC (permalink / raw)
To: ell
[-- Attachment #1: Type: text/plain, Size: 725 bytes --]
On 02/01/2019 07:41 AM, Michał 'Khorne' Lowas-Rzechonek wrote:
> From: Michał Lowas-Rzechonek <michal.lowas-rzechonek@silvair.com>
>
> After declaring a signal with l_dbus_interface_signal, we need a way to
> actually publish it.
>
> This commit adds API for this, along with an updated example.
> ---
> ell/dbus-service.c | 98 +++++++++++++++++++++++++++++++++++++++++
> ell/dbus-service.h | 4 ++
> examples/dbus-service.c | 12 ++++-
> 3 files changed, 112 insertions(+), 2 deletions(-)
>
I'm confused why this is needed? You can emit a signal today by doing:
sig = l_dbus_message_new_signal();
l_dbus_message_set_arguments(sig, "...", ...);
l_dbus_send();
Regards,
-Denis
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] dbus: Added l_dbus_signal_emit
2019-02-01 17:39 ` Denis Kenzior
@ 2019-02-01 19:12 ` =?unknown-8bit?q?Micha=C5=82?= 'Khorne' Lowas-Rzechonek
0 siblings, 0 replies; 3+ messages in thread
From: =?unknown-8bit?q?Micha=C5=82?= 'Khorne' Lowas-Rzechonek @ 2019-02-01 19:12 UTC (permalink / raw)
To: ell
[-- Attachment #1: Type: text/plain, Size: 790 bytes --]
Hi Denis,
On 02/01, Denis Kenzior wrote:
> I'm confused why this is needed? You can emit a signal today by doing:
>
> sig = l_dbus_message_new_signal();
> l_dbus_message_set_arguments(sig, "...", ...);
> l_dbus_send();
Hm. I was originally trying to do that, but if I tried to emit a signal
from a method handler, the client wasn't receiving replies... I think
I've seen mismatched serial numers on dbus-monitor, so I deferred
sending the signal until after method reply.
Seems like I must have had a bug somewhere else, the example above works
as expected. I'm going to re-test this and get back to you.
Sorry for the commotion.
--
Michał Lowas-Rzechonek <michal.lowas-rzechonek@silvair.com>
Silvair http://silvair.com
Jasnogórska 44, 31-358 Krakow, POLAND
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2019-02-01 19:12 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-02-01 13:41 [PATCH] dbus: Added l_dbus_signal_emit =?unknown-8bit?q?Micha=C5=82?= 'Khorne' Lowas-Rzechonek
2019-02-01 17:39 ` Denis Kenzior
2019-02-01 19:12 ` =?unknown-8bit?q?Micha=C5=82?= 'Khorne' Lowas-Rzechonek
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.