--
Tiago Vignatti
C3SL - Centro de Computação Científica e Software Livre
www.c3sl.ufpr.br
>From 6e0692f6a5757b6d838d857bdb68596a5208c6e2 Mon Sep 17 00:00:00 2001
From: Tiago Vignatti <[EMAIL PROTECTED]>
Date: Wed, 1 Oct 2008 21:15:15 -0300
Subject: [PATCH] X event queue mutex.
A mutex is needed because the X event queue is a critical region. Though
the X event queue is re-entrant, we cannot guarantee the simultaneous
processing by both main and input threads.
Signed-off-by: Tiago Vignatti <[EMAIL PROTECTED]>
---
mi/mieq.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 55 insertions(+), 0 deletions(-)
diff --git a/mi/mieq.c b/mi/mieq.c
index 0a1b740..f9f9d8f 100644
--- a/mi/mieq.c
+++ b/mi/mieq.c
@@ -53,6 +53,10 @@ in this Software without prior written authorization from The Open Group.
# include "extinit.h"
# include "exglobals.h"
+#ifdef INPUT_THREAD
+#include <pthread.h>
+#endif
+
#ifdef DPMSExtension
# include "dpmsproc.h"
# define DPMS_SERVER
@@ -81,6 +85,13 @@ typedef struct _EventQueue {
static EventQueueRec miEventQueue;
+#ifdef INPUT_THREAD
+/* We need mutex because the X event queue is a critical region.
+Though the X event queue is re-entrant, we cannot guarantee the
+simultaneous processing by both main and input threads. */
+pthread_mutex_t miEventQueueMutex = PTHREAD_MUTEX_INITIALIZER;
+#endif
+
Bool
mieqInit(void)
{
@@ -122,6 +133,9 @@ mieqResizeEvents(int min_size)
void
mieqEnqueue(DeviceIntPtr pDev, xEvent *e)
{
+#ifdef INPUT_THREAD
+ pthread_mutex_lock(&miEventQueueMutex);
+#endif
unsigned int oldtail = miEventQueue.tail, newtail;
EventListPtr evt;
int isMotion = 0;
@@ -146,6 +160,9 @@ mieqEnqueue(DeviceIntPtr pDev, xEvent *e)
if (laste->nevents > 6) {
ErrorF("[mi] mieqEnqueue: more than six valuator events; dropping.\n");
+#ifdef INPUT_THREAD
+ pthread_mutex_unlock(&miEventQueueMutex);
+#endif
return;
}
if (oldtail == miEventQueue.head ||
@@ -157,10 +174,16 @@ mieqEnqueue(DeviceIntPtr pDev, xEvent *e)
((lastkbp->deviceid & DEVICE_BITS) !=
(v->deviceid & DEVICE_BITS))) {
ErrorF("[mi] mieqEnequeue: out-of-order valuator event; dropping.\n");
+#ifdef INPUT_THREAD
+ pthread_mutex_unlock(&miEventQueueMutex);
+#endif
return;
}
memcpy((laste->events[laste->nevents++].event), e, sizeof(xEvent));
+#ifdef INPUT_THREAD
+ pthread_mutex_unlock(&miEventQueueMutex);
+#endif
return;
}
@@ -176,6 +199,9 @@ mieqEnqueue(DeviceIntPtr pDev, xEvent *e)
if (newtail == miEventQueue.head) {
ErrorF("[mi] EQ overflowing. The server is probably stuck "
"in an infinite loop.\n");
+#ifdef INPUT_THREAD
+ pthread_mutex_unlock(&miEventQueueMutex);
+#endif
return;
}
miEventQueue.tail = newtail;
@@ -193,6 +219,9 @@ mieqEnqueue(DeviceIntPtr pDev, xEvent *e)
if (!evt->event)
{
ErrorF("[mi] Running out of memory. Tossing event.\n");
+#ifdef INPUT_THREAD
+ pthread_mutex_unlock(&miEventQueueMutex);
+#endif
return;
}
}
@@ -212,24 +241,43 @@ mieqEnqueue(DeviceIntPtr pDev, xEvent *e)
miEventQueue.events[oldtail].pDev = pDev;
miEventQueue.lastMotion = isMotion;
+#ifdef INPUT_THREAD
+ pthread_mutex_unlock(&miEventQueueMutex);
+#endif
}
void
mieqSwitchScreen(DeviceIntPtr pDev, ScreenPtr pScreen, Bool fromDIX)
{
+#ifdef INPUT_THREAD
+ pthread_mutex_lock(&miEventQueueMutex);
+#endif
+
EnqueueScreen(pDev) = pScreen;
if (fromDIX)
DequeueScreen(pDev) = pScreen;
+
+#ifdef INPUT_THREAD
+ pthread_mutex_unlock(&miEventQueueMutex);
+#endif
}
void
mieqSetHandler(int event, mieqHandler handler)
{
+#ifdef INPUT_THREAD
+ pthread_mutex_lock(&miEventQueueMutex);
+#endif
+
if (handler && miEventQueue.handlers[event])
ErrorF("[mi] mieq: warning: overriding existing handler %p with %p for "
"event %d\n", miEventQueue.handlers[event], handler, event);
miEventQueue.handlers[event] = handler;
+
+#ifdef INPUT_THREAD
+ pthread_mutex_unlock(&miEventQueueMutex);
+#endif
}
/**
@@ -304,6 +352,10 @@ mieqProcessInputEvents(void)
xEvent* event,
*master_event = NULL;
+#ifdef INPUT_THREAD
+ pthread_mutex_lock(&miEventQueueMutex);
+#endif
+
while (miEventQueue.head != miEventQueue.tail) {
if (screenIsSaved == SCREEN_SAVER_ON)
dixSaveScreens (serverClient, SCREEN_SAVER_OFF, ScreenSaverReset);
@@ -390,5 +442,8 @@ mieqProcessInputEvents(void)
miPointerUpdateSprite(e->pDev);
}
}
+#ifdef INPUT_THREAD
+ pthread_mutex_unlock(&miEventQueueMutex);
+#endif
}
--
1.5.4.3
_______________________________________________
xorg mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/xorg