From de4b24f63e62a39b2cb10a8c58c54d86559f7f26 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Tue, 7 Aug 2018 14:04:44 -0400 Subject: [PATCH 17/51] session-worker: don't switch VTs if we're already on the right VT commit 5b5dccbd shows that switching VTs to the same VT isn't exactly a no-op. In order to prevent unnecessary wakeups, avoid switching VTs if the worker is already on the correct VT. --- daemon/gdm-session-worker.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c index 0322037e0..fd6470bab 100644 --- a/daemon/gdm-session-worker.c +++ b/daemon/gdm-session-worker.c @@ -936,91 +936,101 @@ fix_terminal_vt_mode (GdmSessionWorker *worker, if (ioctl (tty_fd, KDGETMODE, &kernel_display_mode) < 0) { g_debug ("GdmSessionWorker: couldn't query kernel display mode: %m"); succeeded = FALSE; } if (kernel_display_mode == KD_TEXT) { goto out; } /* VT is in the anti-social state of VT_AUTO + KD_GRAPHICS, * fix it. */ succeeded = handle_terminal_vt_switches (worker, tty_fd); mode_fixed = TRUE; out: if (!succeeded) { g_error ("GdmSessionWorker: couldn't set up terminal, aborting..."); return; } g_debug ("GdmSessionWorker: VT mode did %sneed to be fixed", mode_fixed? "" : "not "); } static void jump_to_vt (GdmSessionWorker *worker, int vt_number) { int fd; int active_vt_tty_fd; + int active_vt = -1; + struct vt_stat vt_state = { 0 }; g_debug ("GdmSessionWorker: jumping to VT %d", vt_number); active_vt_tty_fd = open ("/dev/tty0", O_RDWR | O_NOCTTY); if (worker->priv->session_tty_fd != -1) { fd = worker->priv->session_tty_fd; g_debug ("GdmSessionWorker: first setting graphics mode to prevent flicker"); if (ioctl (fd, KDSETMODE, KD_GRAPHICS) < 0) { g_debug ("GdmSessionWorker: couldn't set graphics mode: %m"); } /* It's possible that the current VT was left in a broken * combination of states (KD_GRAPHICS with VT_AUTO), that * can't be switched away from. This call makes sure things * are set in a way that VT_ACTIVATE should work and * VT_WAITACTIVE shouldn't hang. */ fix_terminal_vt_mode (worker, active_vt_tty_fd); } else { fd = active_vt_tty_fd; } handle_terminal_vt_switches (worker, fd); - if (ioctl (fd, VT_ACTIVATE, vt_number) < 0) { - g_debug ("GdmSessionWorker: couldn't initiate jump to VT %d: %m", - vt_number); - } else if (ioctl (fd, VT_WAITACTIVE, vt_number) < 0) { - g_debug ("GdmSessionWorker: couldn't finalize jump to VT %d: %m", - vt_number); + if (ioctl (fd, VT_GETSTATE, &vt_state) <= 0) { + g_debug ("GdmSessionWorker: couldn't get current VT: %m"); + } else { + active_vt = vt_state.v_active; + } + + if (active_vt != vt_number) { + if (ioctl (fd, VT_ACTIVATE, vt_number) < 0) { + g_debug ("GdmSessionWorker: couldn't initiate jump to VT %d: %m", + vt_number); + } else if (ioctl (fd, VT_WAITACTIVE, vt_number) < 0) { + g_debug ("GdmSessionWorker: couldn't finalize jump to VT %d: %m", + vt_number); + } } close (active_vt_tty_fd); } static void gdm_session_worker_set_state (GdmSessionWorker *worker, GdmSessionWorkerState state) { if (worker->priv->state == state) return; worker->priv->state = state; g_object_notify (G_OBJECT (worker), "state"); } static void gdm_session_worker_uninitialize_pam (GdmSessionWorker *worker, int status) { g_debug ("GdmSessionWorker: uninitializing PAM"); if (worker->priv->pam_handle == NULL) return; gdm_session_worker_get_username (worker, NULL); if (worker->priv->state >= GDM_SESSION_WORKER_STATE_SESSION_OPENED) { pam_close_session (worker->priv->pam_handle, 0); gdm_session_auditor_report_logout (worker->priv->auditor); -- 2.27.0