Bug#470882: /dev/gpmctl freezes acknowledge
Samuel Thibault
samuel.thibault at ens-lyon.org
Tue Nov 11 21:24:53 UTC 2008
tags 470882 + patch
thanks
Hello,
Christoph Berg, le Sat 25 Oct 2008 20:47:08 +0200, a écrit :
> I suspect the following code from old_main() is bogus:
>
> if(kd_mode != KD_TEXT && !option.repeater && !option.force_repeat) {
> wait_text(&mouse_table[1].fd);
>
> What does it mean to be "in text mode"? What if X is started later?
As already said, that's not a problem.
> Does gpm assume that all X users will need to enable a repeater?
Precisely no.
The problem is that you both want a mouse on the text console and a
mouse in X. The correct way is to use a repeater: gpm reads
/dev/input/mice, and repeats to X. Now, gpm tries to play nice with X
servers that would read /dev/input/mice themselves: if a repeater is not
setup, then when not in text mode gpm closes the mouse (to let X open
it).
The unfortunate effect here is that it waits without handling clients.
The attached patch fixes that: when not in text mode, the mouse
is closed, but the select() loop continues. I had to change the
timeout of select, I have made it 2 seconds, like the latency of the
previously-used wait_text(). That should fix the hang of clients.
Samuel
-------------- next part --------------
--- src/daemon/old_main.c.orig 2008-11-11 22:06:41.000000000 +0100
+++ src/daemon/old_main.c 2008-11-11 22:06:25.000000000 +0100
@@ -130,10 +130,8 @@
FD_SET(mouse_table[eventFlag].fd,&selSet);
}
else
- while((pending=select(maxfd+1,&selSet,NULL_SET,NULL_SET,&timeout))==0){
- selSet=readySet;
+ if((pending=select(maxfd+1,&selSet,NULL_SET,NULL_SET,&timeout))==0)
resetTimeout();
- } /* go on */
if(opt_resize) { /* did the console resize? */
get_console_size(&event);
@@ -168,12 +166,24 @@
if (ioctl(fd, KDGETMODE, &kd_mode) < 0)
gpm_report(GPM_PR_OOPS,GPM_MESS_IOCTL_KDGETMODE);
close(fd);
- if(kd_mode != KD_TEXT && !option.repeater && !option.force_repeat) {
- wait_text(&mouse_table[1].fd);
- maxfd=max(maxfd,mouse_table[1].fd);
- readySet=connSet;
- FD_SET(mouse_table[1].fd,&readySet);
- continue; /* reselect */
+ if (!option.repeater && !option.force_repeat) {
+ if (mouse_table[1].fd >= 0 && kd_mode != KD_TEXT) {
+ /* Non-text mode, close mouse */
+ close(mouse_table[1].fd);
+ FD_CLR(mouse_table[1].fd,&readySet);
+ mouse_table[1].fd=-1;
+ } else if (mouse_table[1].fd < 0 && kd_mode == KD_TEXT) {
+ /* Back to text mode, reopen mouse */
+ if ((mouse_table[1].fd=open((mouse_table[1].opt_dev),O_RDWR))<0)
+ gpm_report(GPM_PR_OOPS,GPM_MESS_OPEN,(mouse_table[1].opt_dev));
+ else {
+ if ((mouse_table[1].m_type)->init)
+ (mouse_table[1].m_type)=((mouse_table[1].m_type)->init)(mouse_table[1].fd, (mouse_table[1].m_type)->flags, (mouse_table[1].m_type), mouse_argc[1],
+ mouse_argv[1]);
+ maxfd=max(maxfd,mouse_table[1].fd);
+ FD_SET(mouse_table[1].fd,&readySet);
+ }
+ }
}
}
@@ -185,7 +195,7 @@
for (i=1; i <= 1+opt_double; i++) {
which_mouse=mouse_table+i; /* used to access options */
- if (FD_ISSET(which_mouse->fd,&selSet)) {
+ if (which_mouse->fd >= 0 && FD_ISSET(which_mouse->fd,&selSet)) {
FD_CLR(which_mouse->fd,&selSet); pending--;
if (processMouse(which_mouse->fd, &event, (which_mouse->m_type), kd_mode))
/* pass it to the client, if any
--- src/headers/gpmInt.h.orig 2008-11-11 22:01:25.000000000 +0100
+++ src/headers/gpmInt.h 2008-11-11 22:01:32.000000000 +0100
@@ -33,7 +33,7 @@
/*....................................... old gpmCfg.h */
/* timeout for the select() syscall */
-#define SELECT_TIME 86400 /* one day */
+#define SELECT_TIME 2 /* two seconds */
#ifdef HAVE_LINUX_TTY_H
#include <linux/tty.h>
More information about the pkg-gpm-devel
mailing list