summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libsystemd-terminal/sysview-internal.h2
-rw-r--r--src/libsystemd-terminal/sysview.c66
-rw-r--r--src/libsystemd-terminal/sysview.h2
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,