XQuartz: mieq: Wait for the server to finish initializing before letting other threads mieqEnqueue
Avoid possible race condition whereby one thread might call mieqEnqueue before InitAndStartDevices finishes (cherry picked from commit 94e417ac87a98cd5c6bf2d7c495d702748398931)
This commit is contained in:
		
							parent
							
								
									b339052340
								
							
						
					
					
						commit
						ca46c01869
					
				
							
								
								
									
										14
									
								
								dix/main.c
								
								
								
								
							
							
						
						
									
										14
									
								
								dix/main.c
								
								
								
								
							| 
						 | 
				
			
			@ -233,6 +233,12 @@ static int indexForScanlinePad[ 65 ] = {
 | 
			
		|||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef XQUARTZ
 | 
			
		||||
#include <pthread.h>
 | 
			
		||||
 | 
			
		||||
BOOL serverInitComplete = FALSE;
 | 
			
		||||
pthread_mutex_t serverInitCompleteMutex = PTHREAD_MUTEX_INITIALIZER;
 | 
			
		||||
pthread_cond_t serverInitCompleteCond = PTHREAD_COND_INITIALIZER;
 | 
			
		||||
 | 
			
		||||
int dix_main(int argc, char *argv[], char *envp[])
 | 
			
		||||
#else
 | 
			
		||||
int main(int argc, char *argv[], char *envp[])
 | 
			
		||||
| 
						 | 
				
			
			@ -377,6 +383,14 @@ int main(int argc, char *argv[], char *envp[])
 | 
			
		|||
	    }
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#ifdef XQUARTZ
 | 
			
		||||
    /* Let the other threads know the server is done with its init */
 | 
			
		||||
    pthread_mutex_lock(&serverInitCompleteMutex);
 | 
			
		||||
    serverInitComplete = TRUE;
 | 
			
		||||
    pthread_cond_broadcast(&serverInitCompleteCond);
 | 
			
		||||
    pthread_mutex_unlock(&serverInitCompleteMutex);
 | 
			
		||||
#endif
 | 
			
		||||
        
 | 
			
		||||
	NotifyParentProcess();
 | 
			
		||||
 | 
			
		||||
	Dispatch();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										32
									
								
								mi/mieq.c
								
								
								
								
							
							
						
						
									
										32
									
								
								mi/mieq.c
								
								
								
								
							| 
						 | 
				
			
			@ -36,11 +36,6 @@ in this Software without prior written authorization from The Open Group.
 | 
			
		|||
#include <dix-config.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef XQUARTZ
 | 
			
		||||
#include  <pthread.h>
 | 
			
		||||
static pthread_mutex_t miEventQueueMutex = PTHREAD_MUTEX_INITIALIZER;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
# include   <X11/X.h>
 | 
			
		||||
# include   <X11/Xmd.h>
 | 
			
		||||
# include   <X11/Xproto.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -86,6 +81,25 @@ typedef struct _EventQueue {
 | 
			
		|||
static EventQueueRec miEventQueue;
 | 
			
		||||
static EventListPtr masterEvents; /* for use in mieqProcessInputEvents */
 | 
			
		||||
 | 
			
		||||
#ifdef XQUARTZ
 | 
			
		||||
#include  <pthread.h>
 | 
			
		||||
static pthread_mutex_t miEventQueueMutex = PTHREAD_MUTEX_INITIALIZER;
 | 
			
		||||
 | 
			
		||||
extern BOOL serverInitComplete;
 | 
			
		||||
extern pthread_mutex_t serverInitCompleteMutex;
 | 
			
		||||
extern pthread_cond_t serverInitCompleteCond;
 | 
			
		||||
 | 
			
		||||
static inline void wait_for_server_init(void) {
 | 
			
		||||
    /* If the server hasn't finished initializing, wait for it... */
 | 
			
		||||
    if(!serverInitComplete) {
 | 
			
		||||
        pthread_mutex_lock(&serverInitCompleteMutex);
 | 
			
		||||
        while(!serverInitComplete)
 | 
			
		||||
            pthread_cond_wait(&serverInitCompleteCond, &serverInitCompleteMutex);
 | 
			
		||||
        pthread_mutex_unlock(&serverInitCompleteMutex);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
Bool
 | 
			
		||||
mieqInit(void)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -144,6 +158,7 @@ mieqEnqueue(DeviceIntPtr pDev, xEvent *e)
 | 
			
		|||
    int                    evlen;
 | 
			
		||||
 | 
			
		||||
#ifdef XQUARTZ
 | 
			
		||||
    wait_for_server_init();
 | 
			
		||||
    pthread_mutex_lock(&miEventQueueMutex);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -247,14 +262,7 @@ mieqEnqueue(DeviceIntPtr pDev, xEvent *e)
 | 
			
		|||
        evt->event->u.keyButtonPointer.time = miEventQueue.lastEventTime;
 | 
			
		||||
 | 
			
		||||
    miEventQueue.lastEventTime = evt->event->u.keyButtonPointer.time;
 | 
			
		||||
 | 
			
		||||
    /* Avoid possible crash when multithreaded and mieqEnqueue is called before 
 | 
			
		||||
     * InitAndStartDevices finishes.
 | 
			
		||||
     */
 | 
			
		||||
    if(pDev && pDev->spriteInfo && pDev->spriteInfo->sprite)
 | 
			
		||||
    miEventQueue.events[oldtail].pScreen = EnqueueScreen(pDev);
 | 
			
		||||
    else 
 | 
			
		||||
        miEventQueue.events[oldtail].pScreen = NULL;
 | 
			
		||||
    miEventQueue.events[oldtail].pDev = pDev;
 | 
			
		||||
 | 
			
		||||
    miEventQueue.lastMotion = isMotion;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue