--
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

Reply via email to