diff options
author | Jasper St. Pierre <jstpierre@mecheye.net> | 2014-02-25 12:23:57 -0500 |
---|---|---|
committer | Jasper St. Pierre <jstpierre@mecheye.net> | 2014-03-17 17:01:16 -0400 |
commit | a22e5252509332417380aa8169f6f58225cbe502 (patch) | |
tree | 1284591e7e9c24ffaaabd78eb327f95e47e27ae9 /daemon/gdm-display.c | |
parent | 3d7c84b0fe5a5805c8a58350f2517b58972b9844 (diff) | |
download | gdm-a22e5252509332417380aa8169f6f58225cbe502.tar.gz |
display: Clean up old signal handlers
The signal handlers here are intended to be used if the slave itself
tries to stop, for instance if the server or greeter die, and will
try to finish the display on its own.
Letting the signal handler run again will finish the display *again*
after an idle, meaning we have this path:
gdm_display_finish
gdm_display_unmanage
on_server_stopped
queue_finish
... idle ...
gdm_display_finish
gdm_display_unmanage
on_server_stopped
queue_finish
...
This might have been an infinite loop, except for the fact that GDM
smartly has code to detect the failure state where the X server
starts up and stops sufficiently quickly, and in that case transitions
the display to the FAILED state, which causes GdmDisplayStore to
unref the last ref on the GdmDisplay.
Since the finish is still queued, finish_idle runs, and very quickly
discovers that our object is no longer a GdmDisplay, so this very
quickly manifests into a:
gdm_display_finish: assertion 'GDM_IS_DISPLAY (display)' failed
error. Not before poking a hole and corrupting some memory trying
to clear the finish_idle_id, however.
Diffstat (limited to 'daemon/gdm-display.c')
-rw-r--r-- | daemon/gdm-display.c | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c index f966b52a..486d167e 100644 --- a/daemon/gdm-display.c +++ b/daemon/gdm-display.c @@ -686,6 +686,10 @@ gdm_display_real_unmanage (GdmDisplay *display) g_timer_stop (display->priv->slave_timer); if (display->priv->slave != NULL) { + g_signal_handlers_disconnect_by_func (display->priv->slave, + G_CALLBACK (on_slave_started), display); + g_signal_handlers_disconnect_by_func (display->priv->slave, + G_CALLBACK (on_slave_stopped), display); gdm_slave_stop (display->priv->slave); g_object_unref (display->priv->slave); display->priv->slave = NULL; |