From: Paweł Szewczyk
Date: Mon, 6 May 2019 13:20:32 +0000 (+0200)
Subject: unit_start: Make unit actions asynchronous
X-Git-Tag: submit/tizen/20190531.084218~2^2
X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=fb141c206318cc9c100c1f6ff563e7e3d176fb39;p=platform%2Fcore%2Fsystem%2Factivationd.git
unit_start: Make unit actions asynchronous
The response from systemd can be delayed resulting in blocking of the
event processor. We can prevent this by making actions on units
asynchronous.
Change-Id: I175420639820da9ae0a2b0bf4e2a817a68a5fa76
Signed-off-by: Paweł Szewczyk
---
diff --git a/include/systemd_dbus.h b/include/systemd_dbus.h
index 3e00476..f248a09 100644
--- a/include/systemd_dbus.h
+++ b/include/systemd_dbus.h
@@ -42,6 +42,19 @@ int epc_dbus_call(char *service, char *obj, char *interface, char *method,
epc_dbus_call_simple(SYSTEMD_SERVICE, OBJ, INTF, METHOD, \
ARGS, ##__VA_ARGS__)
+typedef sd_bus_message_handler_t epc_dbus_handler_t;
+
+int epc_dbus_call_async(char *service, char *obj, char *interface, char *method,
+ sd_bus_error *error, epc_dbus_handler_t cb,
+ void *user_data, char *args, ...);
+
+#define epc_dbus_call_simple_async(SRV, OBJ, INTF, METHOD, CB, DATA, ARGS, ...) \
+ epc_dbus_call_async(SRV, OBJ, INTF, METHOD, NULL, CB, DATA, ARGS, ##__VA_ARGS__)
+
+#define epc_dbus_call_systemd_simple_async(OBJ, INTF, METHOD, CB, DATA, ARGS, ...) \
+ epc_dbus_call_simple_async(SYSTEMD_SERVICE, OBJ, INTF, METHOD, CB, DATA, \
+ ARGS, ##__VA_ARGS__)
+
int epc_acquire_systemd_bus(sd_bus **bus);
void epc_set_systemd_private(bool);
diff --git a/src/action/unit_start.c b/src/action/unit_start.c
index ea2853e..21bbd92 100644
--- a/src/action/unit_start.c
+++ b/src/action/unit_start.c
@@ -23,6 +23,21 @@
#include "systemd_dbus.h"
#include "common.h"
+static int unit_action_handler(sd_bus_message *m, void *userdata, sd_bus_error *ret_error)
+{
+ struct action_executed_event *exe_info = userdata;
+ int ret;
+
+ if (!exe_info)
+ return -EINVAL;
+
+ exe_info->result = 0;
+ ret = event_processor_report_event(&exe_info->event);
+ epc_event_unref(&exe_info->event);
+
+ return ret;
+}
+
static int start_unit(struct epc_action *action,
struct action_executed_event *exe_info)
{
@@ -66,9 +81,11 @@ static int start_unit(struct epc_action *action,
return 0;
}
- ret = epc_dbus_call_systemd_simple(SYSTEMD_OBJ,
+ ret = epc_dbus_call_systemd_simple_async(SYSTEMD_OBJ,
SYSTEMD_MANAGER_INTERFACE,
unit_action,
+ unit_action_handler,
+ exe_info,
"ss",
unit_name,
"replace");
@@ -78,7 +95,8 @@ static int start_unit(struct epc_action *action,
else
log_kmsg("Starting unit: %s", unit_name);
- exe_info->result = ret;
+ exe_info->result = -EPROBE_DEFER;
+ epc_event_ref(&exe_info->event);
return 0;
}
diff --git a/src/util/systemd_dbus.c b/src/util/systemd_dbus.c
index fe3d2b5..f632e12 100644
--- a/src/util/systemd_dbus.c
+++ b/src/util/systemd_dbus.c
@@ -29,6 +29,38 @@
static sd_bus *systemd_bus = NULL;
static bool epc_systemd_private = false;
+int epc_dbus_call_async(char *service, char *obj, char *interface, char *method,
+ sd_bus_error *error, epc_dbus_handler_t cb,
+ void *user_data, char *types, ...)
+{
+ _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
+ int ret;
+
+ ret = epc_acquire_systemd_bus(&bus);
+ if (ret < 0)
+ return ret;
+
+ ret = sd_bus_message_new_method_call(bus, &m, service, obj, interface, method);
+ if (ret < 0)
+ goto fail;
+
+ if (types) {
+ va_list args;
+
+ va_start(args, types);
+ ret = sd_bus_message_appendv(m, types, args);
+ va_end(args);
+ if (ret < 0)
+ goto fail;
+ }
+
+ return sd_bus_call_async(bus, NULL, m, cb, user_data, 0);
+
+fail:
+ return ret;
+}
+
int epc_dbus_call(char *service, char *obj, char *interface, char *method,
sd_bus_error *error, sd_bus_message **out_msg,
char *types, ...)