Fix drain_console unregistration

Bug introduced by 9dca441670
xfree86: add a hook to replace the new console handler.

console_handler was not being set, making the server eat up CPU spinning
in WaitForSomething selecting consoleFd over and over again, every time
trying to unregister drain_console without success due to
console_handler being NULL.

Let's just fix the unregistration in xf86SetConsoleHandler() and use that.

But wait, there could be a catch: If some driver replaced the handler using
xf86SetConsoleHandler(), the unregistration in xf86CloseConsole will unregister
that one. I don't understand Xorg well enough to know whether this poses a
problem (could mess up driver deinit somehow or something like that). As it is,
xf86SetConsoleHandler() doesn't offer any way to prevent this (i.e. check which
handler is currently registered).

I had been using it for two days on my machine that previously hit 100% CPU
several times a day. That has now gone away without any new problems appearing.

Signed-off-by: Tomas Trnka <tomastrnka@gmx.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Tomáš Trnka 2011-10-11 09:11:18 +02:00 committed by Peter Hutterer
parent 2cb63180fa
commit 323869f329
2 changed files with 10 additions and 13 deletions

View File

@ -601,16 +601,15 @@ xf86AddGeneralHandler(int fd, InputHandlerProc proc, pointer data)
InputHandlerProc InputHandlerProc
xf86SetConsoleHandler(InputHandlerProc proc, pointer data) xf86SetConsoleHandler(InputHandlerProc proc, pointer data)
{ {
static InputHandlerProc handler = NULL; static IHPtr handler = NULL;
InputHandlerProc old_handler = handler; IHPtr old_handler = handler;
if (old_handler) if (old_handler)
xf86RemoveGeneralHandler(old_handler); xf86RemoveGeneralHandler(old_handler);
xf86AddGeneralHandler(xf86Info.consoleFd, proc, data); handler = xf86AddGeneralHandler(xf86Info.consoleFd, proc, data);
handler = proc;
return old_handler; return (old_handler) ? old_handler->ihproc : NULL;
} }
static void static void

View File

@ -45,15 +45,12 @@ static char vtname[11];
static struct termios tty_attr; /* tty state to restore */ static struct termios tty_attr; /* tty state to restore */
static int tty_mode; /* kbd mode to restore */ static int tty_mode; /* kbd mode to restore */
static void *console_handler;
static void static void
drain_console(int fd, void *closure) drain_console(int fd, void *closure)
{ {
errno = 0; errno = 0;
if (tcflush(fd, TCIOFLUSH) == -1 && errno == EIO) { if (tcflush(fd, TCIOFLUSH) == -1 && errno == EIO) {
xf86RemoveGeneralHandler(console_handler); xf86SetConsoleHandler(NULL, NULL);
console_handler = NULL;
} }
} }
@ -257,10 +254,11 @@ xf86CloseConsole(void)
return; return;
} }
if (console_handler) { /*
xf86RemoveGeneralHandler(console_handler); * unregister the drain_console handler
console_handler = NULL; * - what to do if someone else changed it in the meantime?
}; */
xf86SetConsoleHandler(NULL, NULL);
/* Back to text mode ... */ /* Back to text mode ... */
SYSCALL(ret = ioctl(xf86Info.consoleFd, KDSETMODE, KD_TEXT)); SYSCALL(ret = ioctl(xf86Info.consoleFd, KDSETMODE, KD_TEXT));