Messages in this thread Patch in this message | | | Date | Tue, 08 Jun 1999 20:06:10 -0700 | From | Nate Eldredge <> | Subject | [OT for linux-kernel] Re: Problems with starting X |
| |
Thomas Molina wrote:
> I'm not sure what is going on here, but I get a delay in starting X > after rebooting. The attached "logs" are from capturing the output of > "xtrace xinit". log1 is the first instance of the command where X > starts normally. log2 is the second instance, where it takes about 30 > seconds to bring up X. My inspection of the traces show that the two > logs are almost identical. Processor ids are different of course. The > only other difference is the point at which the output from XFree starts > appearing. This happens later in the output from the "normal" case than > it does in the "problem" case.
Hi,
I think this is a bug in X (specifically xinit) that I found some time ago. It's a race condition; xinit expects to be sent SIGUSR1 from the X-server when it finishes starting, so it installs a handler, forks to start the server, and enters `pause'. However, if the server finishes before xinit reaches the `pause', the signal will arrive too soon and `pause' will sleep until another signal arrives. This is the SIGALRM for the 15-second timeout.
You can see from your strace that in the okay case, SIGUSR1 awakens the `pause', but in the problem case SIGUSR1 happened earlier and SIGALRM woke it up.
A patch I wrote follows. This was against 3.3.3, but as far as I can tell they haven't changed anything in that arena. I *did* report it, around the end of February it looks like, but I guess they decided not to fix it. This blocks SIGUSR1 and uses `sigsuspend' to wait for it, eliminating this race.
The change to `fork' from `vfork' is just pedantry; technically one can't do the stuff they do in a `vfork' child.
Btw, I hunted it down by using strace's -T option, which shows time spent in a system call. Also, it would be easier to interpret this if you used an strace that groks new system calls; Debian's 3.99 is a good one. (Yes, I've submitted code for it.)
--- xc/programs/xinit/xinit.c Mon Mar 2 03:56:37 1998 +++ xc/programs/xinit/xinit.c.new Sun Feb 28 20:56:47 1999 @@ -500,9 +500,17 @@ startServer(server) char *server[]; { - serverpid = vfork(); + sigset_t s, old; + sigemptyset(&s); + sigaddset(&s, SIGUSR1); + sigprocmask(SIG_BLOCK, &s, &old); + + serverpid = fork(); switch(serverpid) { case 0: + /* Unblock */ + sigprocmask(SIG_SETMASK, &old, NULL); + /* * don't hang on read/write to control tty */ @@ -570,8 +578,9 @@ * you can easily adjust this value. */ alarm (15); - pause (); + sigsuspend(&old); alarm (0); + sigprocmask(SIG_SETMASK, &old, NULL); if (waitforserver() == 0) { Error("unable to connect to X server\r\n");
--
Nate Eldredge nate@cartsys.com
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |