Subject: Re: proposed fix for XF4 crashing
To: IWAMOTO Toshihiro <iwamoto@sat.t.u-tokyo.ac.jp>
From: Matthieu Herrb <matthieu.herrb@laas.fr>
List: tech-x11
Date: 01/09/2002 01:22:07
You wrote (in your message from Tuesday 8)
>
> My guess is that the crashes are due to race between pointer motion
> event queueing (which happens from signal handler) and removal of
> events from the queue.
>
Totally removing the SIGIO handler is not a good idea.
The code handling the events from SIGIO is supposed to be
safe. However, there's a bug in XFree86 4.1.0 that causes malloc/free
to be called from the sig handler, which is bad.
The following patch, by Keith Packard, form XFree86 CVS repository
fixes this bug. Other users that have reported the same kind of
crashes say the server doesn't crash anymore with this patch.
===================================================================
RCS file: /home/anoncvs/cvs-public/xc/programs/Xserver/hw/xfree86/input/mouse/mouse.c,v
retrieving revision 1.43
retrieving revision 1.44
diff -u -p -r1.43 -r1.44
--- xc/programs/Xserver/hw/xfree86/input/mouse/mouse.c 2001/05/18 20:22:30 1.43
+++ xc/programs/Xserver/hw/xfree86/input/mouse/mouse.c 2001/07/06 08:02:37 1.44
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/input/mouse/mouse.c,v 1.42 2001/05/15 18:22:22 paulo Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/input/mouse/mouse.c,v 1.43 2001/05/18 20:22:30 tsi Exp $ */
/*
*
* Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
@@ -386,6 +386,14 @@ InitProtocols(void)
return TRUE;
}
+static void MouseBlockHandler(pointer data,
+ struct timeval **waitTime,
+ pointer LastSelectMask);
+
+static void MouseWakeupHandler(pointer data,
+ int i,
+ pointer LastSelectMask);
+
/* Process options common to all mouse types. */
static void
MouseCommonOptions(InputInfoPtr pInfo)
@@ -411,6 +419,8 @@ MouseCommonOptions(InputInfoPtr pInfo)
if (pMse->emulate3Buttons) {
xf86Msg(X_CONFIG, "%s: Emulate3Buttons, Emulate3Timeout: %d\n",
pInfo->name, pMse->emulate3Timeout);
+ RegisterBlockAndWakeupHandlers (MouseBlockHandler, MouseWakeupHandler,
+ (pointer) pInfo);
}
pMse->chordMiddle = xf86SetBoolOption(pInfo->options, "ChordMiddle", FALSE);
@@ -1822,18 +1832,17 @@ static char hitachMap[16] = { 0, 2, 1
#define reverseBits(map, b) (((b) & ~0x0f) | map[(b) & 0x0f])
static CARD32
-buttonTimer(OsTimerPtr timer, CARD32 now, pointer arg)
+buttonTimer(InputInfoPtr pInfo)
{
- InputInfoPtr pInfo;
MouseDevPtr pMse;
int sigstate;
int id;
- pInfo = arg;
pMse = pInfo->private;
sigstate = xf86BlockSIGIO ();
+ pMse->emulate3Pending = FALSE;
if ((id = stateTab[pMse->emulateState][4][0]) != 0) {
xf86PostButtonEvent(pInfo->dev, 0, abs(id), (id >= 0), 0, 0);
pMse->emulateState = stateTab[pMse->emulateState][4][2];
@@ -1845,10 +1854,42 @@ buttonTimer(OsTimerPtr timer, CARD32 now
return 0;
}
+static void MouseBlockHandler(pointer data,
+ struct timeval **waitTime,
+ pointer LastSelectMask)
+{
+ InputInfoPtr pInfo = (InputInfoPtr) data;
+ MouseDevPtr pMse = (MouseDevPtr) pInfo->private;
+ int ms;
+
+ if (pMse->emulate3Pending)
+ {
+ ms = pMse->emulate3Expires - GetTimeInMillis ();
+ if (ms <= 0)
+ ms = 0;
+ AdjustWaitForDelay (waitTime, ms);
+ }
+}
+
+static void MouseWakeupHandler(pointer data,
+ int i,
+ pointer LastSelectMask)
+{
+ InputInfoPtr pInfo = (InputInfoPtr) data;
+ MouseDevPtr pMse = (MouseDevPtr) pInfo->private;
+ int ms;
+
+ if (pMse->emulate3Pending)
+ {
+ ms = pMse->emulate3Expires - GetTimeInMillis ();
+ if (ms <= 0)
+ buttonTimer (pInfo);
+ }
+}
+
static void
MouseDoPostEvent(InputInfoPtr pInfo, int buttons, int dx, int dy)
{
- static OsTimerPtr timer = NULL;
MouseDevPtr pMse;
int truebuttons, emulateButtons;
int id, change;
@@ -1890,13 +1931,10 @@ MouseDoPostEvent(InputInfoPtr pInfo, int
stateTab[pMse->emulateState][emulateButtons][2];
if (stateTab[pMse->emulateState][4][0] != 0) {
- timer = TimerSet(timer, 0, pMse->emulate3Timeout, buttonTimer,
- pInfo);
+ pMse->emulate3Expires = GetTimeInMillis () + pMse->emulate3Timeout;
+ pMse->emulate3Pending = TRUE;
} else {
- if (timer) {
- TimerFree(timer);
- timer = NULL;
- }
+ pMse->emulate3Pending = FALSE;
}
}
===================================================================
RCS file: /home/anoncvs/cvs-public/xc/programs/Xserver/hw/xfree86/os-support/xf86OSmouse.h,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -p -r1.14 -r1.15
--- xc/programs/Xserver/hw/xfree86/os-support/xf86OSmouse.h 2001/03/07 16:21:04 1.14
+++ xc/programs/Xserver/hw/xfree86/os-support/xf86OSmouse.h 2001/07/06 08:02:39 1.15
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/xf86OSmouse.h,v 1.13 2001/03/04 01:43:28 tsi Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/xf86OSmouse.h,v 1.14 2001/03/07 16:21:04 paulo Exp $ */
/*
* Copyright (c) 1997-1999 by The XFree86 Project, Inc.
@@ -140,6 +140,8 @@ typedef struct _MouseDevRec {
InputInfoPtr pInfo;
int origProtocolID;
const char * origProtocol;
+ Bool emulate3Pending;/* timer waiting */
+ CARD32 emulate3Expires;/* time to fire emulation code */
} MouseDevRec, *MouseDevPtr;
/* Z axis mapping */
--
Matthieu