After some experimentation I came to realize that it is not possible to send a response to a message at later time if handler is registered with sd_bus_add_object_vtable for some object and interface. The message must be processed and reply send in function that given to sd_bus_vtable. To work around this one has to process messages with sd_bus_process(bus_, &msg). And scan msg for path and other information. Unfortunately with this approach introspection is not automatic. On Tue, 15 Jan 2019 at 19:06, Jean Valjean <valjean.jean1802@xxxxxxxxx> wrote: > > Thank you for your explanation, Lenart. I tried different approach. > Everything is running on a single thread. I have a global > `sd_bus_message* test` variable. I do the following > > int method_handler(sd_bus_message* m, void* /*userdata*/, > sd_bus_error* /*error*/) { > test = sd_bus_message_ref(m); > return 0; > } > > And create an object with > > static const sd_bus_vtable vtable[] = { > SD_BUS_VTABLE_START(0), > SD_BUS_PROPERTY("Description", "s", property_handler, 0, > SD_BUS_VTABLE_PROPERTY_CONST), > SD_BUS_METHOD("Do", "s", "s", method_handler, SD_BUS_VTABLE_UNPRIVILEGED), > SD_BUS_VTABLE_END > }; > > r = sd_bus_add_object_vtable( > bus_, > nullptr, > path, > interface, > vtable, > nullptr > ); > > Connect to bus, request service name and start waiting for incoming messages > sd_bus_open_user(&bus_); > sd_bus_request_name(bus_, service_name_, 0); > > while(true){ > sd_bus_process(bus_, NULL); > > if (r > 0) { > continue; > } > > if (test) { > int r = sd_bus_message_get_errno(test); > > if(!r) { > const char* reply = "reply"; > r = sd_bus_reply_method_return(test, "s", reply); > }else { > std::cout << "Error\n"; > } > > sd_bus_message_unref(test); > test = nullptr; > } > r = sd_bus_wait(bus_, 1e+6); > } > > sd_bus_reply_method_return(test, "s", reply) doesn't do anything if > called outside method_handler. > I think that the call that is responsible for invoking method_handler > sends an error back to the client when method_handler returns. > Hence the connection to client is actually closed when I call > sd_bus_reply_method_return(test, "s", reply). > In that case I suppose sd_bus_message_get_errno should return an error > but it doesn't. > > I'm using mailinglist for the first time so I'm not sure it that OK to > post code here. Hope it will show correctly in your email client. > > > On Tue, 15 Jan 2019 at 15:05, Lennart Poettering <mzerqung@xxxxxxxxxxx> wrote: > > > > On Mo, 14.01.19 21:07, Jean Valjean (valjean.jean1802@xxxxxxxxx) wrote: > > > > > I want to send a reply to a method call outside method_handler. Is it > > > possible? > > > In the method_handler I increase reference count of sd_bus_message and send > > > it to the other thread. From there I want to call > > > sd_bus_reply_method_return to send a reply but get Unknown method or > > > interface error when I invoke method with bussctl --user call. If I call > > > the return method from method_handler everything works as expected. > > > > Note that sd-bus is not thread-safe on its own. It's threads-aware > > however: if you are careful to lock around all invocations of sd_bus > > using a single connection (and its associated messages) is generally > > fine, but it's up to you to carefully lock. > > > > So yeah, it's certainly OK to reply to an incoming bus call msgs > > outside of the stack method handler stack frame, but if that means > > threads, then make sure you know what you are doing. > > > > Lennart > > > > -- > > Lennart Poettering, Red Hat _______________________________________________ systemd-devel mailing list systemd-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/systemd-devel