diff options
Diffstat (limited to 'src/libsystemd-terminal')
-rw-r--r-- | src/libsystemd-terminal/sysview-internal.h | 2 | ||||
-rw-r--r-- | src/libsystemd-terminal/sysview.c | 66 | ||||
-rw-r--r-- | src/libsystemd-terminal/sysview.h | 2 |
3 files changed, 62 insertions, 8 deletions
diff --git a/src/libsystemd-terminal/sysview-internal.h b/src/libsystemd-terminal/sysview-internal.h index 39ff933eaa..f1fd4b5f53 100644 --- a/src/libsystemd-terminal/sysview-internal.h +++ b/src/libsystemd-terminal/sysview-internal.h @@ -113,6 +113,7 @@ struct sysview_context { sd_bus *sysbus; struct udev *ud; uint64_t custom_sid; + unsigned int n_probe; Hashmap *seat_map; Hashmap *session_map; @@ -137,6 +138,7 @@ struct sysview_context { bool running : 1; bool scanned : 1; bool rescan : 1; + bool settled : 1; }; int sysview_context_rescan(sysview_context *c); diff --git a/src/libsystemd-terminal/sysview.c b/src/libsystemd-terminal/sysview.c index cd61ea44e7..550f0305af 100644 --- a/src/libsystemd-terminal/sysview.c +++ b/src/libsystemd-terminal/sysview.c @@ -474,6 +474,14 @@ static int context_raise(sysview_context *c, sysview_event *event, int def) { return c->running ? c->event_fn(c, c->userdata, event) : def; } +static int context_raise_settle(sysview_context *c) { + sysview_event event = { + .type = SYSVIEW_EVENT_SETTLE, + }; + + return context_raise(c, &event, 0); +} + static int context_raise_seat_add(sysview_context *c, sysview_seat *seat) { sysview_event event = { .type = SYSVIEW_EVENT_SEAT_ADD, @@ -585,6 +593,21 @@ static int context_raise_session_refresh(sysview_context *c, sysview_session *se return context_raise(c, &event, 0); } +static void context_settle(sysview_context *c) { + int r; + + if (c->n_probe <= 0 || --c->n_probe > 0) + return; + + log_debug("sysview: settle"); + + c->settled = true; + + r = context_raise_settle(c); + if (r < 0) + log_debug_errno(r, "sysview: callback failed on settle: %m"); +} + static void context_add_device(sysview_context *c, sysview_device *device) { sysview_session *session; Iterator i; @@ -1251,7 +1274,8 @@ static int context_ld_list_seats_fn(sd_bus *bus, log_debug("sysview: ListSeats on logind failed: %s: %s", error->name, error->message); - return -sd_bus_error_get_errno(error); + r = -sd_bus_error_get_errno(error); + goto settle; } r = sd_bus_message_enter_container(reply, 'a', "(so)"); @@ -1277,12 +1301,16 @@ static int context_ld_list_seats_fn(sd_bus *bus, r = sd_bus_message_exit_container(reply); if (r < 0) - return r; + goto error; - return 0; + r = 0; + goto settle; error: - return log_debug_errno(r, "sysview: erroneous ListSeats response from logind: %m"); + log_debug_errno(r, "sysview: erroneous ListSeats response from logind: %m"); +settle: + context_settle(c); + return r; } static int context_ld_list_sessions_fn(sd_bus *bus, @@ -1299,7 +1327,8 @@ static int context_ld_list_sessions_fn(sd_bus *bus, log_debug("sysview: ListSessions on logind failed: %s: %s", error->name, error->message); - return -sd_bus_error_get_errno(error); + r = -sd_bus_error_get_errno(error); + goto settle; } r = sd_bus_message_enter_container(reply, 'a', "(susso)"); @@ -1341,12 +1370,16 @@ static int context_ld_list_sessions_fn(sd_bus *bus, r = sd_bus_message_exit_container(reply); if (r < 0) - return r; + goto error; - return 0; + r = 0; + goto settle; error: - return log_debug_errno(r, "sysview: erroneous ListSessions response from logind: %m"); + log_debug_errno(r, "sysview: erroneous ListSessions response from logind: %m"); +settle: + context_settle(c); + return r; } static int context_ld_scan(sysview_context *c) { @@ -1376,6 +1409,9 @@ static int context_ld_scan(sysview_context *c) { if (r < 0) return r; + if (!c->settled) + ++c->n_probe; + /* request session list */ m = sd_bus_message_unref(m); @@ -1397,6 +1433,9 @@ static int context_ld_scan(sysview_context *c) { if (r < 0) return r; + if (!c->settled) + ++c->n_probe; + return 0; } @@ -1461,6 +1500,8 @@ void sysview_context_stop(sysview_context *c) { c->running = false; c->scanned = false; + c->settled = false; + c->n_probe = 0; c->event_fn = NULL; c->userdata = NULL; c->scan_src = sd_event_source_unref(c->scan_src); @@ -1474,6 +1515,8 @@ static int context_scan_fn(sd_event_source *s, void *userdata) { Iterator i; int r; + c->rescan = false; + if (!c->scanned) { r = context_ld_scan(c); if (r < 0) @@ -1491,6 +1534,7 @@ static int context_scan_fn(sd_event_source *s, void *userdata) { } c->scanned = true; + context_settle(c); return 0; } @@ -1501,6 +1545,12 @@ int sysview_context_rescan(sysview_context *c) { if (!c->running) return 0; + if (!c->rescan) { + c->rescan = true; + if (!c->settled) + ++c->n_probe; + } + if (c->scan_src) return sd_event_source_set_enabled(c->scan_src, SD_EVENT_ONESHOT); else diff --git a/src/libsystemd-terminal/sysview.h b/src/libsystemd-terminal/sysview.h index aa5527ff32..71e56e7ebf 100644 --- a/src/libsystemd-terminal/sysview.h +++ b/src/libsystemd-terminal/sysview.h @@ -51,6 +51,8 @@ typedef struct sysview_context sysview_context; */ enum { + SYSVIEW_EVENT_SETTLE, + SYSVIEW_EVENT_SEAT_ADD, SYSVIEW_EVENT_SEAT_REMOVE, |