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