Commit 8b2a0a68 authored by Jiri (George) Lebl's avatar Jiri (George) Lebl Committed by George Lebl

killall the xdmcp slaves first and then wait for them en-masse. This

Tue Jul 29 12:15:54 2003  George Lebl <jirka@5z.com>

	* daemon/display.c, daemon/gdm.c: killall the xdmcp slaves first and
	  then wait for them en-masse.  This should make large xdmcp server
	  much faster when shutting gdm down.  Make races with the waitpid
	  stuff harder to happen.  In the worst case we wait 10 seconds.

	* daemon/misc.[ch], daemon/gdm.c, daemon/slave.c, daemon/server.c
	  daemon/verify-*.c: implement a sleep using select which doesn't
	  stop on signals (it restarts self), which is useful in a whole
	  bunch of places, and also avoids the alarm vs. sleep thing
	  which we were completely forgotting about.
parent e527e911
Tue Jul 29 12:15:54 2003 George Lebl <jirka@5z.com>
* daemon/display.c, daemon/gdm.c: killall the xdmcp slaves first and
then wait for them en-masse. This should make large xdmcp server
much faster when shutting gdm down. Make races with the waitpid
stuff harder to happen. In the worst case we wait 10 seconds.
* daemon/misc.[ch], daemon/gdm.c, daemon/slave.c, daemon/server.c
daemon/verify-*.c: implement a sleep using select which doesn't
stop on signals (it restarts self), which is useful in a whole
bunch of places, and also avoids the alarm vs. sleep thing
which we were completely forgotting about.
Tue Jul 29 11:10:20 2003 George Lebl <jirka@5z.com>
* daemon/misc.c: apparently _SC_OPEN_MAX can be rediculously high
......
......@@ -166,13 +166,21 @@ static void
whack_old_slave (GdmDisplay *d)
{
time_t t = time (NULL);
gboolean waitsleep = TRUE;
/* if we have DISPLAY_DEAD set, then this has already been killed */
if (d->dispstat == DISPLAY_DEAD)
waitsleep = FALSE;
/* Kill slave */
if (d->slavepid > 1 &&
kill (d->slavepid, SIGTERM) == 0) {
(d->dispstat == DISPLAY_DEAD || kill (d->slavepid, SIGTERM) == 0)) {
int exitstatus;
int ret;
wait_again:
sleep (10);
if (waitsleep)
/* wait for some signal, yes this is a race */
sleep (10);
waitsleep = TRUE;
errno = 0;
ret = waitpid (d->slavepid, &exitstatus, WNOHANG);
if (ret <= 0) {
......@@ -184,8 +192,8 @@ wait_again:
ve_signal_was_notified (SIGHUP) ||
t + 10 <= time (NULL)) {
gdm_debug ("whack_old_slave: GOT ANOTHER SIGTERM (or it was 10 secs already), killing slave again");
kill (d->slavepid, SIGTERM);
t = time (NULL);
kill (d->slavepid, SIGTERM);
goto wait_again;
} else if (ret < 0 && errno == EINTR) {
goto wait_again;
......@@ -358,9 +366,8 @@ gdm_display_unmanage (GdmDisplay *d)
* slave dies, which should be ASAP though */
whack_old_slave (d);
if (d->type == TYPE_LOCAL)
d->dispstat = DISPLAY_DEAD;
else /* TYPE_XDMCP,TYPE_FLEXI,TYPE_FLEXI_XNEST */
d->dispstat = DISPLAY_DEAD;
if (d->type != TYPE_LOCAL)
gdm_display_dispose (d);
gdm_debug ("gdm_display_unmanage: Display stopped");
......
......@@ -887,6 +887,7 @@ void
gdm_final_cleanup (void)
{
GSList *list, *li;
gboolean first;
gdm_debug ("gdm_final_cleanup");
......@@ -899,17 +900,21 @@ gdm_final_cleanup (void)
extra_process = 0;
}
list = g_slist_copy (displays);
for (li = list; li != NULL; li = li->next) {
/* First off whack all XDMCP and FLEXI_XNEST
slaves, we'll wait for them later */
for (li = displays; li != NULL; li = li->next) {
GdmDisplay *d = li->data;
/* XDMCP and FLEXI_XNEST are safe to kill
* immediately */
if (d->type == TYPE_XDMCP ||
d->type == TYPE_FLEXI_XNEST)
gdm_display_unmanage (d);
d->type == TYPE_FLEXI_XNEST) {
/* set to DEAD so that we won't kill it again */
d->dispstat = DISPLAY_DEAD;
if (d->slavepid > 1)
kill (d->slavepid, SIGTERM);
}
}
g_slist_free (list);
/* Now completely unmanage the local servers */
first = TRUE;
list = g_slist_copy (displays);
/* somewhat of a hack to kill last server
* started first. This mostly makes things end up on
......@@ -917,15 +922,38 @@ gdm_final_cleanup (void)
list = g_slist_reverse (list);
for (li = list; li != NULL; li = li->next) {
GdmDisplay *d = li->data;
if (d->type == TYPE_XDMCP ||
d->type == TYPE_FLEXI_XNEST)
continue;
/* HACK! Wait 2 seconds between killing of local servers
* because X is stupid and full of races and will hang my
* keyboard if I don't */
if (li != list)
sleep (2);
if ( ! first) {
/* there could be signals happening
here */
gdm_sleep_no_signal (2);
}
first = FALSE;
gdm_display_unmanage (d);
}
g_slist_free (list);
/* and now kill and wait for the XDMCP and FLEXI_XNEST
slaves. unmanage will not kill slaves we have already
killed unless a SIGTERM was sent in the meantime */
list = g_slist_copy (displays);
for (li = list; li != NULL; li = li->next) {
GdmDisplay *d = li->data;
/* XDMCP and FLEXI_XNEST are safe to kill
* immediately */
if (d->type == TYPE_XDMCP ||
d->type == TYPE_FLEXI_XNEST)
gdm_display_unmanage (d);
}
g_slist_free (list);
/* Close stuff */
if (GdmXdmcp)
......@@ -1055,9 +1083,12 @@ deal_with_x_crashes (GdmDisplay *d)
int ret;
int killsignal = SIGTERM;
int storeerrno;
errno = 0;
ret = waitpid (extra_process, &status, WNOHANG);
do {
/* wait for some signal */
pause ();
/* wait for some signal, yes this is a race */
if (ret <= 0)
sleep (10);
errno = 0;
ret = waitpid (extra_process, &status, WNOHANG);
storeerrno = errno;
......@@ -1225,7 +1256,7 @@ gdm_cleanup_children (void)
d->servpid = 0;
/* race avoider */
sleep (1);
gdm_sleep_no_signal (1);
}
/* null all these, they are not valid most definately */
......
......@@ -1617,4 +1617,21 @@ gdm_root_user (void)
return root_user;
}
void
gdm_sleep_no_signal (int secs)
{
time_t endtime = time (NULL)+secs;
while (secs > 0) {
struct timeval tv;
/* Wait 30 seconds. */
tv.tv_sec = secs;
tv.tv_usec = 0;
select (0, NULL, NULL, NULL, &tv);
/* don't want to use sleep since we're using alarm
for pinging */
secs = endtime - time (NULL);
}
}
/* EOF */
......@@ -126,6 +126,7 @@ const char *gdm_root_user (void);
void gdm_signal_ignore (int signal);
void gdm_signal_default (int signal);
void gdm_sleep_no_signal (int secs);
#endif /* GDM_MISC_H */
......
......@@ -504,7 +504,7 @@ do_server_wait (GdmDisplay *d)
* just wait a few seconds and hope things just work,
* fortunately there is no such case yet and probably
* never will, but just for code anality's sake */
sleep (5);
gdm_sleep_no_signal (5);
} else if (d->server_uid != 0) {
int i;
......@@ -528,7 +528,7 @@ do_server_wait (GdmDisplay *d)
i++) {
d->dsp = XOpenDisplay (d->name);
if (d->dsp == NULL)
sleep (1);
gdm_sleep_no_signal (1);
else
d->servstat = SERVER_RUNNING;
}
......
......@@ -865,7 +865,7 @@ gdm_slave_check_user_wants_to_log_in (const char *user)
/* wait for a few seconds to avoid any vt changing race
*/
sleep (1);
gdm_sleep_no_signal (1);
gdm_change_vt (vt);
......@@ -898,7 +898,7 @@ gdm_slave_run (GdmDisplay *display)
if (d->sleep_before_run > 0) {
gdm_debug ("gdm_slave_run: Sleeping %d seconds before server start", d->sleep_before_run);
sleep (d->sleep_before_run);
gdm_sleep_no_signal (d->sleep_before_run);
d->sleep_before_run = 0;
check_notifies_now ();
......@@ -984,7 +984,7 @@ gdm_slave_run (GdmDisplay *display)
if (d->dsp == NULL) {
gdm_debug ("gdm_slave_run: Sleeping %d on a retry", 1+openretries*2);
sleep (1+openretries*2);
gdm_sleep_no_signal (1+openretries*2);
openretries++;
}
}
......@@ -1002,7 +1002,7 @@ gdm_slave_run (GdmDisplay *display)
/* Just a race avoiding sleep, probably not necessary though,
* but doesn't hurt anything */
if ( ! d->handled)
sleep (1);
gdm_sleep_no_signal (1);
if (SERVER_IS_LOCAL (d)) {
gdm_slave_send (GDM_SOP_START_NEXT_LOCAL, FALSE);
......@@ -3484,7 +3484,7 @@ gdm_slave_session_stop (gboolean run_post_session,
gdm_info (_("GDM detected a shutdown or reboot "
"in progress."));
fclose (fp);
while (c + 30 > time (NULL)) {
while (c + 30 >= time (NULL)) {
struct timeval tv;
/* Wait 30 seconds. */
tv.tv_sec = 30;
......
......@@ -167,7 +167,7 @@ authenticate_again:
gdm_slave_greeter_ctl_no_ret (GDM_STOPTIMER, "");
if (pwent == NULL) {
sleep (GdmRetryDelay);
gdm_sleep_no_signal (GdmRetryDelay);
gdm_error (_("Couldn't authenticate user \"%s\""), login);
print_cant_auth_errbox ();
......@@ -181,7 +181,7 @@ authenticate_again:
/* Check whether password is valid */
if (ppasswd == NULL || (ppasswd[0] != '\0' &&
strcmp (crypt (passwd, ppasswd), ppasswd) != 0)) {
sleep (GdmRetryDelay);
gdm_sleep_no_signal (GdmRetryDelay);
gdm_error (_("Couldn't authenticate user \"%s\""), login);
print_cant_auth_errbox ();
......
......@@ -532,7 +532,7 @@ authenticate_again:
gdm_slave_greeter_ctl_no_ret (GDM_STOPTIMER, "");
if (gdm_slave_should_complain ()) {
#ifndef PAM_FAIL_DELAY
sleep (GdmRetryDelay);
gdm_sleep_no_signal (GdmRetryDelay);
#endif /* PAM_FAIL_DELAY */
gdm_error (_("Couldn't authenticate user"));
}
......
......@@ -185,7 +185,7 @@ authenticate_again:
gdm_slave_greeter_ctl_no_ret (GDM_STOPTIMER, "");
if (pwent == NULL) {
sleep (GdmRetryDelay);
gdm_sleep_no_signal (GdmRetryDelay);
gdm_error (_("Couldn't authenticate user \"%s\""), login);
print_cant_auth_errbox ();
......@@ -199,7 +199,7 @@ authenticate_again:
/* Check whether password is valid */
if (ppasswd == NULL || (ppasswd[0] != '\0' &&
strcmp (crypt (passwd, ppasswd), ppasswd) != 0)) {
sleep (GdmRetryDelay);
gdm_sleep_no_signal (GdmRetryDelay);
gdm_error (_("Couldn't authenticate user \"%s\""), login);
print_cant_auth_errbox ();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment