chiark / gitweb /
Remove src/libsystemd-network
[elogind.git] / src / libsystemd-terminal / sysview.c
index 62d9b6606091e7f14bf645be4061b4b5f339abb7..550f0305af0e2590d5b40b3745707c72b1da04d1 100644 (file)
@@ -27,9 +27,7 @@
 #include <systemd/sd-event.h>
 #include <systemd/sd-login.h>
 #include "bus-util.h"
-#include "event-util.h"
 #include "macro.h"
-#include "set.h"
 #include "sysview.h"
 #include "sysview-internal.h"
 #include "udev-util.h"
@@ -476,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,
@@ -587,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;
@@ -975,11 +996,9 @@ static int context_ud_hotplug(sysview_context *c, struct udev_device *d) {
                         return 0;
 
                 r = device_new_ud(&device, seat, type, d);
-                if (r < 0) {
-                        log_debug_errno(r, "sysview: cannot create device for udev-device '%s': %m",
-                                        syspath);
-                        return r;
-                }
+                if (r < 0)
+                        return log_debug_errno(r, "sysview: cannot create device for udev-device '%s': %m",
+                                               syspath);
 
                 context_add_device(c, device);
         }
@@ -1102,10 +1121,8 @@ static int context_ld_seat_new(sysview_context *c, sd_bus_message *signal) {
         int r;
 
         r = sd_bus_message_read(signal, "so", &id, &path);
-        if (r < 0) {
-                log_debug_errno(r, "sysview: cannot parse SeatNew from logind: %m");
-                return r;
-        }
+        if (r < 0)
+                return log_debug_errno(r, "sysview: cannot parse SeatNew from logind: %m");
 
         context_add_seat(c, id);
         return 0;
@@ -1117,10 +1134,8 @@ static int context_ld_seat_removed(sysview_context *c, sd_bus_message *signal) {
         int r;
 
         r = sd_bus_message_read(signal, "so", &id, &path);
-        if (r < 0) {
-                log_debug_errno(r, "sysview: cannot parse SeatRemoved from logind: %m");
-                return r;
-        }
+        if (r < 0)
+                return log_debug_errno(r, "sysview: cannot parse SeatRemoved from logind: %m");
 
         seat = sysview_find_seat(c, id);
         if (!seat)
@@ -1138,10 +1153,8 @@ static int context_ld_session_new(sysview_context *c, sd_bus_message *signal) {
         int r;
 
         r = sd_bus_message_read(signal, "so", &id, &path);
-        if (r < 0) {
-                log_debug_errno(r, "sysview: cannot parse SessionNew from logind: %m");
-                return r;
-        }
+        if (r < 0)
+                return log_debug_errno(r, "sysview: cannot parse SessionNew from logind: %m");
 
         /*
          * As the dbus message didn't contain enough information, we
@@ -1182,9 +1195,8 @@ static int context_ld_session_new(sysview_context *c, sd_bus_message *signal) {
         return 0;
 
 error:
-        log_debug_errno(r, "sysview: failed retrieving information for new session '%s': %m",
-                        id);
-        return r;
+        return log_debug_errno(r, "sysview: failed retrieving information for new session '%s': %m",
+                               id);
 }
 
 static int context_ld_session_removed(sysview_context *c, sd_bus_message *signal) {
@@ -1193,10 +1205,8 @@ static int context_ld_session_removed(sysview_context *c, sd_bus_message *signal
         int r;
 
         r = sd_bus_message_read(signal, "so", &id, &path);
-        if (r < 0) {
-                log_debug_errno(r, "sysview: cannot parse SessionRemoved from logind: %m");
-                return r;
-        }
+        if (r < 0)
+                return log_debug_errno(r, "sysview: cannot parse SessionRemoved from logind: %m");
 
         session = sysview_find_session(c, id);
         if (!session)
@@ -1264,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)");
@@ -1290,12 +1301,15 @@ 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:
         log_debug_errno(r, "sysview: erroneous ListSeats response from logind: %m");
+settle:
+        context_settle(c);
         return r;
 }
 
@@ -1313,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)");
@@ -1355,12 +1370,15 @@ 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:
         log_debug_errno(r, "sysview: erroneous ListSessions response from logind: %m");
+settle:
+        context_settle(c);
         return r;
 }
 
@@ -1391,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);
@@ -1412,6 +1433,9 @@ static int context_ld_scan(sysview_context *c) {
         if (r < 0)
                 return r;
 
+        if (!c->settled)
+                ++c->n_probe;
+
         return 0;
 }
 
@@ -1476,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);
@@ -1489,27 +1515,26 @@ 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) {
-                        log_debug_errno(r, "sysview: logind scan failed: %m");
-                        return r;
-                }
+                if (r < 0)
+                        return log_debug_errno(r, "sysview: logind scan failed: %m");
         }
 
         /* skip device scans if no sessions are available */
         if (hashmap_size(c->session_map) > 0) {
                 r = context_ud_scan(c);
-                if (r < 0) {
-                        log_debug_errno(r, "sysview: udev scan failed: %m");
-                        return r;
-                }
+                if (r < 0)
+                        return log_debug_errno(r, "sysview: udev scan failed: %m");
 
                 HASHMAP_FOREACH(seat, c->seat_map, i)
                         seat->scanned = true;
         }
 
         c->scanned = true;
+        context_settle(c);
 
         return 0;
 }
@@ -1520,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