Merge pull request #805 from dvdhrm/proxy-activation

bus-proxy: make StartServiceByName synchronous
This commit is contained in:
Daniel Mack
2015-07-31 15:03:49 +02:00
3 changed files with 68 additions and 13 deletions
+46 -13
View File
@@ -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;
+9
View File
@@ -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);
+13
View File
@@ -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);