bus: when NULL is specified as property callback, automatically handle serialization on Get()

This commit is contained in:
Lennart Poettering 2013-10-11 06:10:15 +02:00
parent 62b5c2aec1
commit adcdb37476
5 changed files with 65 additions and 19 deletions

View File

@ -108,7 +108,6 @@ bool bus_type_is_trivial(char c) {
return !!memchr(valid, c, sizeof(valid));
}
bool bus_type_is_container(char c) {
static const char valid[] = {
SD_BUS_TYPE_ARRAY,

View File

@ -2103,6 +2103,46 @@ static int method_callbacks_run(
return c->vtable->method.handler(bus, m, u);
}
static int invoke_property_get(
sd_bus *bus,
const sd_bus_vtable *v,
const char *path,
const char *interface,
const char *property,
sd_bus_message *m,
sd_bus_error *error,
void *userdata) {
int r;
void *p;
assert(bus);
assert(v);
if (v->property.get)
return v->property.get(bus, path, interface, property, m, error, userdata);
/* Automatic handling if no callback is defined. */
switch (v->property.signature[0]) {
case SD_BUS_TYPE_STRING:
case SD_BUS_TYPE_OBJECT_PATH:
case SD_BUS_TYPE_SIGNATURE:
p = *(char**) userdata;
break;
default:
p = userdata;
}
r = sd_bus_message_append_basic(m, v->property.signature[0], p);
if (r < 0)
return r;
return 1;
}
static int property_get_set_callbacks_run(
sd_bus *bus,
sd_bus_message *m,
@ -2140,12 +2180,9 @@ static int property_get_set_callbacks_run(
if (r < 0)
return r;
if (c->vtable->property.get) {
r = c->vtable->property.get(bus, m->path, c->interface, c->member, reply, &error, u);
if (r < 0)
return r;
} else
assert_not_reached("automatic properties not supported yet");
r = invoke_property_get(bus, c->vtable, m->path, c->interface, c->member, reply, &error, u);
if (r < 0)
return r;
if (sd_bus_error_is_set(&error)) {
r = sd_bus_reply_method_error(bus, m, &error);
@ -2226,7 +2263,7 @@ static int vtable_append_all_properties(
if (r < 0)
return r;
r = v->property.get(bus, path, c->interface, v->property.member, reply, error, vtable_property_convert_userdata(v, userdata));
r = invoke_property_get(bus, v, path, c->interface, v->property.member, reply, error, vtable_property_convert_userdata(v, userdata));
if (r < 0)
return r;
@ -3588,7 +3625,7 @@ static void free_node_vtable(sd_bus *bus, struct node_vtable *w) {
if (w->interface && w->node && w->vtable) {
const sd_bus_vtable *v;
for (v = w->vtable; v->type != _SD_BUS_VTABLE_END; w++) {
for (v = w->vtable; v->type != _SD_BUS_VTABLE_END; v++) {
struct vtable_member *x = NULL;
switch (v->type) {
@ -3757,6 +3794,7 @@ static int add_object_vtable_internal(
if (!member_name_is_valid(v->property.member) ||
!signature_is_single(v->property.signature, false) ||
!(v->property.get || bus_type_is_basic(v->property.signature[0])) ||
v->flags & SD_BUS_VTABLE_METHOD_NO_REPLY ||
(v->flags & SD_BUS_VTABLE_PROPERTY_INVALIDATE_ONLY && !(v->flags & SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE))) {
r = -EINVAL;
@ -3809,7 +3847,7 @@ fail:
free_node_vtable(bus, c);
bus_node_gc(bus, n);
return 0;
return r;
}
static int remove_object_vtable_internal(
@ -4048,7 +4086,7 @@ static int emit_properties_changed_on_interface(
if (r < 0)
return r;
r = v->vtable->property.get(bus, m->path, interface, *property, m, &error, vtable_property_convert_userdata(v->vtable, u));
r = invoke_property_get(bus, v->vtable, m->path, interface, *property, m, &error, vtable_property_convert_userdata(v->vtable, u));
if (r < 0)
return r;

View File

@ -33,9 +33,9 @@ static int prop_set(sd_bus *bus, const char *path, const char *interface, const
static const sd_bus_vtable vtable[] = {
SD_BUS_VTABLE_START(0),
SD_BUS_METHOD("Hello", "ssas", "a(uu)", 0, NULL),
SD_BUS_METHOD("DeprecatedHello", "", "", SD_BUS_VTABLE_DEPRECATED, NULL),
SD_BUS_METHOD("DeprecatedHelloNoReply", "", "", SD_BUS_VTABLE_DEPRECATED|SD_BUS_VTABLE_METHOD_NO_REPLY, NULL),
SD_BUS_METHOD("Hello", "ssas", "a(uu)", NULL, 0),
SD_BUS_METHOD("DeprecatedHello", "", "", NULL, SD_BUS_VTABLE_DEPRECATED),
SD_BUS_METHOD("DeprecatedHelloNoReply", "", "", NULL, SD_BUS_VTABLE_DEPRECATED|SD_BUS_VTABLE_METHOD_NO_REPLY),
SD_BUS_SIGNAL("Wowza", "sss", 0),
SD_BUS_SIGNAL("DeprecatedWowza", "ut", SD_BUS_VTABLE_DEPRECATED),
SD_BUS_WRITABLE_PROPERTY("AProperty", "s", prop_get, prop_set, 0, 0),

View File

@ -38,7 +38,9 @@
*
* Add in:
*
* automatic properties
* automatic properties for Set()
* automatic NULL method
* allow NULL as signatures in vtable
* node hierarchy updates during dispatching
* emit_interfaces_added/emit_interfaces_removed
*
@ -48,6 +50,8 @@ struct context {
int fds[2];
bool quit;
char *something;
const char *automatic_string_property;
uint32_t automatic_integer_property;
};
static int something_handler(sd_bus *bus, sd_bus_message *m, void *userdata) {
@ -148,15 +152,17 @@ static int notify_test(sd_bus *bus, sd_bus_message *m, void *userdata) {
static const sd_bus_vtable vtable[] = {
SD_BUS_VTABLE_START(0),
SD_BUS_METHOD("AlterSomething", "s", "s", 0, something_handler),
SD_BUS_METHOD("Exit", "", "", 0, exit_handler),
SD_BUS_METHOD("AlterSomething", "s", "s", something_handler, 0),
SD_BUS_METHOD("Exit", "", "", exit_handler, 0),
SD_BUS_WRITABLE_PROPERTY("Something", "s", get_handler, set_handler, 0, 0),
SD_BUS_PROPERTY("AutomaticStringProperty", "s", NULL, offsetof(struct context, automatic_string_property), 0),
SD_BUS_PROPERTY("AutomaticIntegerProperty", "u", NULL, offsetof(struct context, automatic_integer_property), 0),
SD_BUS_VTABLE_END
};
static const sd_bus_vtable vtable2[] = {
SD_BUS_VTABLE_START(0),
SD_BUS_METHOD("NotifyTest", "", "", 0, notify_test),
SD_BUS_METHOD("NotifyTest", "", "", notify_test, 0),
SD_BUS_PROPERTY("Value", "s", value_handler, 10, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_VTABLE_END
};
@ -384,6 +390,9 @@ int main(int argc, char *argv[]) {
zero(c);
c.automatic_integer_property = 4711;
c.automatic_string_property = "dudeldu";
assert_se(socketpair(AF_UNIX, SOCK_STREAM, 0, c.fds) >= 0);
r = pthread_create(&s, NULL, server, &c);

View File

@ -80,7 +80,7 @@ struct sd_bus_vtable {
.start.element_size = sizeof(sd_bus_vtable), \
}
#define SD_BUS_METHOD(_member, _signature, _result, _flags, _handler) \
#define SD_BUS_METHOD(_member, _signature, _result, _handler, _flags) \
{ \
.type = _SD_BUS_VTABLE_METHOD, \
.flags = _flags, \