1
0
mirror of https://github.com/systemd/systemd.git synced 2024-11-06 08:26:52 +03:00

timedate: emit property changed signal after all jobs are completed

Follow-up for 3af0a96c0f (#9684).
This commit is contained in:
Yu Watanabe 2018-07-27 01:32:12 +09:00 committed by Lennart Poettering
parent 9e888a9c5b
commit cf3872bd28

View File

@ -36,6 +36,7 @@ typedef struct UnitStatusInfo {
char *load_state; char *load_state;
char *unit_file_state; char *unit_file_state;
char *active_state; char *active_state;
char *path;
LIST_FIELDS(struct UnitStatusInfo, units); LIST_FIELDS(struct UnitStatusInfo, units);
} UnitStatusInfo; } UnitStatusInfo;
@ -47,7 +48,6 @@ typedef struct Context {
sd_bus_message *cache; sd_bus_message *cache;
sd_bus_slot *slot_job_removed; sd_bus_slot *slot_job_removed;
char *path_ntp_unit;
LIST_HEAD(UnitStatusInfo, units); LIST_HEAD(UnitStatusInfo, units);
} Context; } Context;
@ -65,6 +65,7 @@ static void unit_status_info_free(UnitStatusInfo *p) {
unit_status_info_clear(p); unit_status_info_clear(p);
free(p->name); free(p->name);
free(p->path);
free(p); free(p);
} }
@ -78,7 +79,6 @@ static void context_free(Context *c) {
sd_bus_message_unref(c->cache); sd_bus_message_unref(c->cache);
sd_bus_slot_unref(c->slot_job_removed); sd_bus_slot_unref(c->slot_job_removed);
free(c->path_ntp_unit);
while ((p = c->units)) { while ((p = c->units)) {
LIST_REMOVE(units, c->units, p); LIST_REMOVE(units, c->units, p);
@ -352,8 +352,10 @@ static int context_update_ntp_status(Context *c, sd_bus *bus, sd_bus_message *m)
} }
static int match_job_removed(sd_bus_message *m, void *userdata, sd_bus_error *error) { static int match_job_removed(sd_bus_message *m, void *userdata, sd_bus_error *error) {
const char *path;
Context *c = userdata; Context *c = userdata;
UnitStatusInfo *u;
const char *path;
unsigned n = 0;
int r; int r;
assert(c); assert(c);
@ -365,42 +367,30 @@ static int match_job_removed(sd_bus_message *m, void *userdata, sd_bus_error *er
return 0; return 0;
} }
if (!streq_ptr(path, c->path_ntp_unit)) LIST_FOREACH(units, u, c->units)
return 0; if (streq_ptr(path, u->path))
u->path = mfree(u->path);
else
n += !!u->path;
(void) sd_bus_emit_properties_changed(sd_bus_message_get_bus(m), "/org/freedesktop/timedate1", "org.freedesktop.timedate1", "NTP", NULL); if (n == 0) {
(void) sd_bus_emit_properties_changed(sd_bus_message_get_bus(m), "/org/freedesktop/timedate1", "org.freedesktop.timedate1", "NTP", NULL);
c->slot_job_removed = sd_bus_slot_unref(c->slot_job_removed); c->slot_job_removed = sd_bus_slot_unref(c->slot_job_removed);
c->path_ntp_unit = mfree(c->path_ntp_unit); }
return 0; return 0;
} }
static int unit_start_or_stop(Context *c, UnitStatusInfo *u, sd_bus *bus, sd_bus_error *error, bool start) { static int unit_start_or_stop(UnitStatusInfo *u, sd_bus *bus, sd_bus_error *error, bool start) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
_cleanup_(sd_bus_slot_unrefp) sd_bus_slot *slot = NULL;
const char *path; const char *path;
int r; int r;
assert(c);
assert(u); assert(u);
assert(bus); assert(bus);
assert(error); assert(error);
/* This method may be called frequently. Forget the previous job if it has not completed yet. */
c->slot_job_removed = sd_bus_slot_unref(c->slot_job_removed);
r = sd_bus_match_signal_async(
bus,
&slot,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
"JobRemoved",
match_job_removed, NULL, c);
if (r < 0)
return r;
r = sd_bus_call_method( r = sd_bus_call_method(
bus, bus,
"org.freedesktop.systemd1", "org.freedesktop.systemd1",
@ -419,11 +409,10 @@ static int unit_start_or_stop(Context *c, UnitStatusInfo *u, sd_bus *bus, sd_bus
if (r < 0) if (r < 0)
return bus_log_parse_error(r); return bus_log_parse_error(r);
r = free_and_strdup(&c->path_ntp_unit, path); r = free_and_strdup(&u->path, path);
if (r < 0) if (r < 0)
return log_oom(); return log_oom();
c->slot_job_removed = TAKE_PTR(slot);
return 0; return 0;
} }
@ -824,6 +813,7 @@ static int method_set_time(sd_bus_message *m, void *userdata, sd_bus_error *erro
} }
static int method_set_ntp(sd_bus_message *m, void *userdata, sd_bus_error *error) { static int method_set_ntp(sd_bus_message *m, void *userdata, sd_bus_error *error) {
_cleanup_(sd_bus_slot_unrefp) sd_bus_slot *slot = NULL;
sd_bus *bus = sd_bus_message_get_bus(m); sd_bus *bus = sd_bus_message_get_bus(m);
Context *c = userdata; Context *c = userdata;
UnitStatusInfo *u; UnitStatusInfo *u;
@ -858,6 +848,23 @@ static int method_set_ntp(sd_bus_message *m, void *userdata, sd_bus_error *error
if (r == 0) if (r == 0)
return 1; return 1;
/* This method may be called frequently. Forget the previous job if it has not completed yet. */
LIST_FOREACH(units, u, c->units)
u->path = mfree(u->path);
if (!c->slot_job_removed) {
r = sd_bus_match_signal_async(
bus,
&slot,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
"JobRemoved",
match_job_removed, NULL, c);
if (r < 0)
return r;
}
if (!enable) if (!enable)
LIST_FOREACH(units, u, c->units) { LIST_FOREACH(units, u, c->units) {
if (!streq(u->load_state, "loaded")) if (!streq(u->load_state, "loaded"))
@ -867,7 +874,7 @@ static int method_set_ntp(sd_bus_message *m, void *userdata, sd_bus_error *error
if (q < 0) if (q < 0)
r = q; r = q;
q = unit_start_or_stop(c, u, bus, error, enable); q = unit_start_or_stop(u, bus, error, enable);
if (q < 0) if (q < 0)
r = q; r = q;
} }
@ -881,7 +888,7 @@ static int method_set_ntp(sd_bus_message *m, void *userdata, sd_bus_error *error
if (r < 0) if (r < 0)
continue; continue;
r = unit_start_or_stop(c, u, bus, error, enable); r = unit_start_or_stop(u, bus, error, enable);
break; break;
} }
@ -891,13 +898,16 @@ static int method_set_ntp(sd_bus_message *m, void *userdata, sd_bus_error *error
!streq(u->unit_file_state, "enabled")) !streq(u->unit_file_state, "enabled"))
continue; continue;
r = unit_start_or_stop(c, u, bus, error, enable); r = unit_start_or_stop(u, bus, error, enable);
break; break;
} }
if (r < 0) if (r < 0)
return r; return r;
if (slot)
c->slot_job_removed = TAKE_PTR(slot);
log_info("Set NTP to %sd", enable_disable(enable)); log_info("Set NTP to %sd", enable_disable(enable));
return sd_bus_reply_method_return(m, NULL); return sd_bus_reply_method_return(m, NULL);