Merge pull request #805 from dvdhrm/proxy-activation
bus-proxy: make StartServiceByName synchronous
This commit is contained in:
+46
-13
@@ -71,6 +71,27 @@ static int get_creds_by_message(sd_bus *bus, sd_bus_message *m, uint64_t mask, s
|
||||
return get_creds_by_name(bus, name, mask, _creds, error);
|
||||
}
|
||||
|
||||
static int driver_activation(sd_bus_message *reply, void *userdata, sd_bus_error *error) {
|
||||
_cleanup_bus_message_unref_ sd_bus_message *m = NULL;
|
||||
ProxyActivation *activation = userdata;
|
||||
|
||||
/*
|
||||
* The org.freedesktop.DBus.Peer.Ping() call returned. We don't care
|
||||
* whether this succeeded, failed, was not implemented or timed out. We
|
||||
* cannot assume that the target reacts to this properly. Hence, just
|
||||
* send the reply to the activation request and be done.
|
||||
*/
|
||||
|
||||
m = activation->request; /* claim reference */
|
||||
|
||||
--activation->proxy->n_activations;
|
||||
LIST_REMOVE(activations_by_proxy, activation->proxy->activations, activation);
|
||||
sd_bus_slot_unref(activation->slot);
|
||||
free(activation);
|
||||
|
||||
return synthetic_reply_method_return(m, "u", BUS_START_REPLY_SUCCESS);
|
||||
}
|
||||
|
||||
int bus_proxy_process_driver(Proxy *p, sd_bus *a, sd_bus *b, sd_bus_message *m, SharedPolicy *sp, const struct ucred *ucred, Set *owned_names) {
|
||||
int r;
|
||||
|
||||
@@ -587,6 +608,7 @@ int bus_proxy_process_driver(Proxy *p, sd_bus *a, sd_bus *b, sd_bus_message *m,
|
||||
|
||||
} else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "StartServiceByName")) {
|
||||
_cleanup_bus_message_unref_ sd_bus_message *msg = NULL;
|
||||
ProxyActivation *activation;
|
||||
const char *name;
|
||||
uint32_t flags;
|
||||
|
||||
@@ -606,21 +628,32 @@ int bus_proxy_process_driver(Proxy *p, sd_bus *a, sd_bus *b, sd_bus_message *m,
|
||||
if (r != -ESRCH)
|
||||
return synthetic_reply_method_errno(m, r, NULL);
|
||||
|
||||
r = sd_bus_message_new_method_call(
|
||||
a,
|
||||
&msg,
|
||||
name,
|
||||
"/",
|
||||
"org.freedesktop.DBus.Peer",
|
||||
"Ping");
|
||||
if (r < 0)
|
||||
return synthetic_reply_method_errno(m, r, NULL);
|
||||
if (p->n_activations >= PROXY_ACTIVATIONS_MAX)
|
||||
return synthetic_reply_method_errno(m, -EMFILE, NULL);
|
||||
|
||||
r = sd_bus_send(a, msg, NULL);
|
||||
if (r < 0)
|
||||
return synthetic_reply_method_errno(m, r, NULL);
|
||||
activation = new0(ProxyActivation, 1);
|
||||
if (!activation)
|
||||
return synthetic_reply_method_errno(m, -ENOMEM, NULL);
|
||||
|
||||
return synthetic_reply_method_return(m, "u", BUS_START_REPLY_SUCCESS);
|
||||
r = sd_bus_call_method_async(a,
|
||||
&activation->slot,
|
||||
name,
|
||||
"/",
|
||||
"org.freedesktop.DBus.Peer",
|
||||
"Ping",
|
||||
driver_activation,
|
||||
activation,
|
||||
NULL);
|
||||
if (r < 0) {
|
||||
free(activation);
|
||||
return synthetic_reply_method_errno(m, r, NULL);
|
||||
}
|
||||
|
||||
activation->proxy = p;
|
||||
activation->request = sd_bus_message_ref(m);
|
||||
LIST_PREPEND(activations_by_proxy, p->activations, activation);
|
||||
++p->n_activations;
|
||||
return 1;
|
||||
|
||||
} else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "UpdateActivationEnvironment")) {
|
||||
_cleanup_bus_message_unref_ sd_bus_message *msg = NULL;
|
||||
|
||||
@@ -261,9 +261,18 @@ int proxy_new(Proxy **out, int in_fd, int out_fd, const char *destination) {
|
||||
}
|
||||
|
||||
Proxy *proxy_free(Proxy *p) {
|
||||
ProxyActivation *activation;
|
||||
|
||||
if (!p)
|
||||
return NULL;
|
||||
|
||||
while ((activation = p->activations)) {
|
||||
LIST_REMOVE(activations_by_proxy, p->activations, activation);
|
||||
sd_bus_message_unref(activation->request);
|
||||
sd_bus_slot_unref(activation->slot);
|
||||
free(activation);
|
||||
}
|
||||
|
||||
sd_bus_flush_close_unref(p->local_bus);
|
||||
sd_bus_flush_close_unref(p->destination_bus);
|
||||
set_free_free(p->owned_names);
|
||||
|
||||
@@ -25,6 +25,9 @@
|
||||
#include "bus-xml-policy.h"
|
||||
|
||||
typedef struct Proxy Proxy;
|
||||
typedef struct ProxyActivation ProxyActivation;
|
||||
|
||||
#define PROXY_ACTIVATIONS_MAX (16) /* max parallel activation requests */
|
||||
|
||||
struct Proxy {
|
||||
sd_bus *local_bus;
|
||||
@@ -37,12 +40,22 @@ struct Proxy {
|
||||
Set *owned_names;
|
||||
SharedPolicy *policy;
|
||||
|
||||
LIST_HEAD(ProxyActivation, activations);
|
||||
size_t n_activations;
|
||||
|
||||
bool got_hello : 1;
|
||||
bool queue_overflow : 1;
|
||||
bool message_matched : 1;
|
||||
bool synthetic_matched : 1;
|
||||
};
|
||||
|
||||
struct ProxyActivation {
|
||||
LIST_FIELDS(ProxyActivation, activations_by_proxy);
|
||||
Proxy *proxy;
|
||||
sd_bus_message *request;
|
||||
sd_bus_slot *slot;
|
||||
};
|
||||
|
||||
int proxy_new(Proxy **out, int in_fd, int out_fd, const char *dest);
|
||||
Proxy *proxy_free(Proxy *p);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user