- Made the message queue access to be thread safe. (Using two new
  functions to access the message queue, QUEUE_Lock(), QUEUE_Unlock()
  instead of GlobalLock16()).
- Fixed QUEUE_DumpQueue (used by "info queue <handle>" with the
  wine-debugger).

diff --git a/windows/hook.c b/windows/hook.c
index 5aac94e..c4336cc 100644
--- a/windows/hook.c
+++ b/windows/hook.c
@@ -827,9 +827,11 @@
     MESSAGEQUEUE *queue;
     HANDLE16 hook = 0;
 
-    if ((queue = (MESSAGEQUEUE *)GlobalLock16( hQueue )) != NULL)
+    if ((queue = (MESSAGEQUEUE *)QUEUE_Lock( hQueue )) != NULL)
         hook = queue->hooks[id - WH_MINHOOK];
     if (!hook) hook = HOOK_systemHooks[id - WH_MINHOOK];
+
+    QUEUE_Unlock( queue );
     return hook;
 }
 
@@ -878,9 +880,10 @@
 
     if (hQueue)
     {
-        MESSAGEQUEUE *queue = (MESSAGEQUEUE *)GlobalLock16( hQueue );
+        MESSAGEQUEUE *queue = (MESSAGEQUEUE *)QUEUE_Lock( hQueue );
         data->next = queue->hooks[id - WH_MINHOOK];
         queue->hooks[id - WH_MINHOOK] = handle;
+        QUEUE_Unlock( queue );
     }
     else
     {
@@ -921,9 +924,10 @@
 
     if (data->ownerQueue)
     {
-        MESSAGEQUEUE *queue = (MESSAGEQUEUE *)GlobalLock16( data->ownerQueue );
+        MESSAGEQUEUE *queue = (MESSAGEQUEUE *)QUEUE_Lock( data->ownerQueue );
         if (!queue) return FALSE;
         prevHook = &queue->hooks[data->id - WH_MINHOOK];
+        QUEUE_Unlock( queue );
     }
     else prevHook = &HOOK_systemHooks[data->id - WH_MINHOOK];
 
@@ -979,7 +983,7 @@
 
     /* Now call it */
 
-    if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetFastQueue() ))) return 0;
+    if (!(queue = (MESSAGEQUEUE *)QUEUE_Lock( GetFastQueue() ))) return 0;
     prevHook = queue->hCurHook;
     queue->hCurHook = hook;
     data->flags |= HOOK_INUSE;
@@ -994,6 +998,8 @@
     data->flags &= ~HOOK_INUSE;
     queue->hCurHook = prevHook;
 
+    QUEUE_Unlock( queue );
+
     if (UnMapFunc)
       UnMapFunc( data->id, code, wParamOrig, lParamOrig, wParam, lParam );
 
@@ -1089,7 +1095,7 @@
 {
     MESSAGEQUEUE *queue;
 
-    if ((queue = (MESSAGEQUEUE *)GlobalLock16( hQueue )) != NULL)
+    if ((queue = (MESSAGEQUEUE *)QUEUE_Lock( hQueue )) != NULL)
     {
 	HOOKDATA*	data;
 	HHOOK		hook;
@@ -1106,6 +1112,8 @@
 		} else break;
 	    }
 	}
+
+        QUEUE_Unlock( queue );
     }
 }
 
@@ -1329,9 +1337,12 @@
     /* Note: the *hhook parameter is never used, since we rely on the
      * current hook value from the task queue to find the next hook. */
     MESSAGEQUEUE *queue;
+    LRESULT ret;
 
-    if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetFastQueue() ))) return 0;
-    return CallNextHookEx16( queue->hCurHook, code, wParam, lParam );
+    if (!(queue = (MESSAGEQUEUE *)QUEUE_Lock( GetFastQueue() ))) return 0;
+    ret = CallNextHookEx16( queue->hCurHook, code, wParam, lParam );
+    QUEUE_Unlock( queue );
+    return ret;
 }
 
 
diff --git a/windows/message.c b/windows/message.c
index db9ea24..5b4586c 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -36,8 +36,7 @@
 typedef enum { SYSQ_MSG_ABANDON, SYSQ_MSG_SKIP, 
                SYSQ_MSG_ACCEPT, SYSQ_MSG_CONTINUE } SYSQ_STATUS;
 
-extern MESSAGEQUEUE *pCursorQueue;			 /* queue.c */
-extern MESSAGEQUEUE *pActiveQueue;
+extern HQUEUE16 hCursorQueue;			 /* queue.c */
 
 DWORD MSG_WineStartTicks; /* Ticks at Wine startup */
 
@@ -102,7 +101,7 @@
     UINT16 message = msg->message;
     POINT16 screen_pt, pt;
     HANDLE16 hQ = GetFastQueue();
-    MESSAGEQUEUE *queue = (MESSAGEQUEUE *)GlobalLock16(hQ);
+    MESSAGEQUEUE *queue = (MESSAGEQUEUE *)QUEUE_Lock(hQ);
     BOOL32 eatMsg = FALSE;
     BOOL32 mouseClick = ((message == WM_LBUTTONDOWN) ||
 		         (message == WM_RBUTTONDOWN) ||
@@ -133,15 +132,22 @@
         /* Not for the current task */
         if (queue) QUEUE_ClearWakeBit( queue, QS_MOUSE );
         /* Wake up the other task */
-        queue = (MESSAGEQUEUE *)GlobalLock16( pWnd->hmemTaskQ );
+        QUEUE_Unlock( queue );
+        queue = (MESSAGEQUEUE *)QUEUE_Lock( pWnd->hmemTaskQ );
         if (queue) QUEUE_SetWakeBit( queue, QS_MOUSE );
+
+        QUEUE_Unlock( queue );
         return SYSQ_MSG_ABANDON;
     }
 
 	/* check if hWnd is within hWndScope */
 
     if( hTopWnd && hWnd != hTopWnd )
-	if( !IsChild16(hTopWnd, hWnd) ) return SYSQ_MSG_CONTINUE;
+        if( !IsChild16(hTopWnd, hWnd) )
+        {
+            QUEUE_Unlock( queue );
+            return SYSQ_MSG_CONTINUE;
+        }
 
     if( mouseClick )
     {
@@ -172,9 +178,14 @@
 
 	/* check message filter */
 
-    if (!MSG_CheckFilter(message, filter)) return SYSQ_MSG_CONTINUE;
+    if (!MSG_CheckFilter(message, filter))
+    {
+        QUEUE_Unlock(queue);
+        return SYSQ_MSG_CONTINUE;
+    }
 
-    pCursorQueue = queue;
+    hCursorQueue = queue->self;
+    QUEUE_Unlock(queue);
 
 	/* call WH_MOUSE */
 
@@ -280,11 +291,14 @@
     if (pWnd && (pWnd->hmemTaskQ != GetFastQueue()))
     {
         /* Not for the current task */
-        MESSAGEQUEUE *queue = (MESSAGEQUEUE *)GlobalLock16( GetFastQueue() );
+        MESSAGEQUEUE *queue = (MESSAGEQUEUE *)QUEUE_Lock( GetFastQueue() );
         if (queue) QUEUE_ClearWakeBit( queue, QS_KEY );
+        QUEUE_Unlock( queue );
+        
         /* Wake up the other task */
-        queue = (MESSAGEQUEUE *)GlobalLock16( pWnd->hmemTaskQ );
+        queue = (MESSAGEQUEUE *)QUEUE_Lock( pWnd->hmemTaskQ );
         if (queue) QUEUE_SetWakeBit( queue, QS_KEY );
+        QUEUE_Unlock( queue );
         return SYSQ_MSG_ABANDON;
     }
 
@@ -603,10 +617,16 @@
     QSMCTRL 	  qCtrl = { 0, 1};
     MESSAGEQUEUE *queue, *destQ;
 
-    if (!(queue = (MESSAGEQUEUE*)GlobalLock16( GetFastQueue() ))) return 0;
-    if (!(destQ = (MESSAGEQUEUE*)GlobalLock16( hDestQueue ))) return 0;
+    if (IsTaskLocked() || !IsWindow32(hwnd))
+        return 0;
 
-    if (IsTaskLocked() || !IsWindow32(hwnd)) return 0;
+    if (!(queue = (MESSAGEQUEUE*)QUEUE_Lock( GetFastQueue() ))) return 0;
+
+    if (!(destQ = (MESSAGEQUEUE*)QUEUE_Lock( hDestQueue )))
+    {
+        QUEUE_Unlock( queue );
+        return 0;
+    }
 
     debugSMRL+=4;
     TRACE(sendmsg,"%*sSM: %s [%04x] (%04x -> %04x)\n", 
@@ -664,6 +684,9 @@
     TRACE(sendmsg,"%*sSM: [%04x] returning %08lx\n", prevSMRL, "", msg, qCtrl.lResult);
     debugSMRL-=4;
 
+    QUEUE_Unlock( queue );
+    QUEUE_Unlock( destQ );
+    
     return qCtrl.lResult;
 }
 
@@ -676,11 +699,11 @@
     MESSAGEQUEUE *senderQ;
     MESSAGEQUEUE *queue;
 
-    if (!(queue = (MESSAGEQUEUE*)GlobalLock16( GetFastQueue() ))) return;
+    if (!(queue = (MESSAGEQUEUE*)QUEUE_Lock( GetFastQueue() ))) return;
 
     TRACE(msg,"ReplyMessage, queue %04x\n", queue->self);
 
-    while( (senderQ = (MESSAGEQUEUE*)GlobalLock16( queue->InSendMessageHandle)))
+    while( (senderQ = (MESSAGEQUEUE*)QUEUE_Lock( queue->InSendMessageHandle)))
     {
       TRACE(msg,"\trpm: replying to %08x (%04x -> %04x)\n",
             queue->msg32, queue->self, senderQ->self);
@@ -688,13 +711,21 @@
       if( queue->wakeBits & QS_SENDMESSAGE )
       {
 	QUEUE_ReceiveMessage( queue );
+        QUEUE_Unlock( senderQ );
 	continue; /* ReceiveMessage() already called us */
       }
 
       if(!(senderQ->wakeBits & QS_SMRESULT) ) break;
       if (THREAD_IsWin16(THREAD_Current())) OldYield();
+      
+      QUEUE_Unlock( senderQ );
     } 
-    if( !senderQ ) { TRACE(msg,"\trpm: done\n"); return; }
+    if( !senderQ )
+    {
+      TRACE(msg,"\trpm: done\n");
+      QUEUE_Unlock( queue );
+      return;
+    }
 
     senderQ->SendMessageReturn = result;
     TRACE(msg,"\trpm: smResult = %08x, result = %08lx\n", 
@@ -706,6 +737,9 @@
     QUEUE_SetWakeBit( senderQ, QS_SMRESULT );
     if (THREAD_IsWin16( THREAD_Current() ))
         DirectedYield( senderQ->thdb->teb.htask16 );
+
+    QUEUE_Unlock( senderQ );
+    QUEUE_Unlock( queue );
 }
 
 
@@ -746,7 +780,7 @@
         QMSG *qmsg;
         
 	hQueue   = GetFastQueue();
-        msgQueue = (MESSAGEQUEUE *)GlobalLock16( hQueue );
+        msgQueue = (MESSAGEQUEUE *)QUEUE_Lock( hQueue );
         if (!msgQueue) return FALSE;
         msgQueue->changeBits = 0;
 
@@ -852,12 +886,19 @@
         if (peek)
         {
             if (!(flags & PM_NOYIELD)) UserYield();
+            
+            QUEUE_Unlock( msgQueue );
             return FALSE;
         }
         msgQueue->wakeMask = mask;
         QUEUE_WaitBits( mask );
+        QUEUE_Unlock( msgQueue );
     }
 
+    /* instead of unlocking queue for every break condition, all break
+       condition will fall here */
+    QUEUE_Unlock( msgQueue );
+    
       /* We got a message */
     if (flags & PM_REMOVE)
     {
@@ -1557,18 +1598,21 @@
 
     TDB *currTask = (TDB *)GlobalLock16( GetCurrentTask() );
     HQUEUE16 hQueue = currTask? currTask->hQueue : 0;
-    MESSAGEQUEUE *msgQueue = (MESSAGEQUEUE *)GlobalLock16( hQueue );
+    MESSAGEQUEUE *msgQueue = (MESSAGEQUEUE *)QUEUE_Lock( hQueue );
     if (!msgQueue) return WAIT_FAILED;
 
     if (nCount > MAXIMUM_WAIT_OBJECTS-1)
     {
         SetLastError( ERROR_INVALID_PARAMETER );
+        QUEUE_Unlock( msgQueue );
         return WAIT_FAILED;
     }
 
     msgQueue->changeBits = 0;
     msgQueue->wakeMask = dwWakeMask;
 
+    QUEUE_Unlock( msgQueue );
+    
     /* Add the thread event to the handle list */
     for (i = 0; i < nCount; i++) handles[i] = pHandles[i];
     handles[nCount] = currTask->thdb->event;
@@ -2058,10 +2102,14 @@
 BOOL32 WINAPI InSendMessage32(void)
 {
     MESSAGEQUEUE *queue;
+    BOOL32 ret;
 
-    if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetFastQueue() )))
+    if (!(queue = (MESSAGEQUEUE *)QUEUE_Lock( GetFastQueue() )))
         return 0;
-    return (BOOL32)queue->InSendMessageHandle;
+    ret = (BOOL32)queue->InSendMessageHandle;
+
+    QUEUE_Unlock( queue );
+    return ret;
 }
 
 /***********************************************************************
diff --git a/windows/queue.c b/windows/queue.c
index ff3ff13..463d78c 100644
--- a/windows/queue.c
+++ b/windows/queue.c
@@ -28,8 +28,58 @@
 static MESSAGEQUEUE *pMouseQueue = NULL;  /* Queue for last mouse message */
 static MESSAGEQUEUE *pKbdQueue = NULL;    /* Queue for last kbd message */
 
-MESSAGEQUEUE *pCursorQueue = NULL; 
-MESSAGEQUEUE *pActiveQueue = NULL;
+HQUEUE16 hCursorQueue = 0;
+HQUEUE16 hActiveQueue = 0;
+
+
+/***********************************************************************
+ *	     QUEUE_Lock
+ *
+ * Fonction for getting a 32 bit pointer on queue strcture. For thread
+ * safeness programmers should use this function instead of GlobalLock to
+ * retrieve a pointer on the structure. QUEUE_Unlock should also be called
+ * when access to the queue structure is not required anymore.
+ */
+MESSAGEQUEUE *QUEUE_Lock( HQUEUE16 hQueue )
+{
+    MESSAGEQUEUE *queue;
+
+    SYSTEM_LOCK();
+    queue = GlobalLock16( hQueue );
+    if ( !queue || (queue->magic != QUEUE_MAGIC) )
+    {
+        SYSTEM_UNLOCK();
+        return NULL;
+    }
+
+    queue->lockCount++;
+    SYSTEM_UNLOCK();
+
+    return queue;
+}
+
+/***********************************************************************
+ *	     QUEUE_Unlock
+ *
+ * Use with QUEUE_Lock to get a thread safe acces to message queue
+ * structure
+ */
+void QUEUE_Unlock( MESSAGEQUEUE *queue )
+{
+    if (queue)
+    {
+        SYSTEM_LOCK();
+
+        if ( --queue->lockCount == 0 )
+        {
+            DeleteCriticalSection ( &queue->cSection );
+            GlobalFree16( queue->self );
+        }
+    
+        SYSTEM_UNLOCK();
+    }
+}
+
 
 /***********************************************************************
  *	     QUEUE_DumpQueue
@@ -38,8 +88,7 @@
 {
     MESSAGEQUEUE *pq; 
 
-    if (!(pq = (MESSAGEQUEUE*) GlobalLock16( hQueue )) ||
-        GlobalSize16(hQueue) != sizeof(MESSAGEQUEUE))
+    if (!(pq = (MESSAGEQUEUE*) QUEUE_Lock( hQueue )) )
     {
         WARN(msg, "%04x is not a queue handle\n", hQueue );
         return;
@@ -48,21 +97,24 @@
     DUMP(    "next: %12.4x  Intertask SendMessage:\n"
              "thread: %10p  ----------------------\n"
              "hWnd: %12.8x\n"
-             "firstMsg: %8p  lastMsg: %8p"
-             "msgCount: %8.4x msg: %11.8x\n"
-             "wParam: %10.8x   lParam: %8.8x\n"
-             "lRet: %12.8x\n"
+             "firstMsg: %8p   msg:     %11.8x\n"
+             "lastMsg:  %8p   wParam:   %10.8x\n"
+             "msgCount: %8.4x   lParam:   %10.8x\n"
+             "lockCount: %7.4x   lRet:   %12.8x\n"
              "wWinVer: %9.4x  ISMH: %10.4x\n"
              "paints: %10.4x  hSendTask: %5.4x\n"
              "timers: %10.4x  hPrevSend: %5.4x\n"
              "wakeBits: %8.4x\n"
              "wakeMask: %8.4x\n"
              "hCurHook: %8.4x\n",
-             pq->next, pq->thdb, pq->hWnd32, pq->firstMsg, pq->lastMsg,
-             pq->msgCount, pq->msg32, pq->wParam32,(unsigned)pq->lParam,
-             (unsigned)pq->SendMessageReturn, pq->wWinVersion, pq->InSendMessageHandle,
+             pq->next, pq->thdb, pq->hWnd32, pq->firstMsg, pq->msg32,
+             pq->lastMsg, pq->wParam32, pq->msgCount, (unsigned)pq->lParam,
+             (unsigned)pq->lockCount, (unsigned)pq->SendMessageReturn,
+             pq->wWinVersion, pq->InSendMessageHandle,
              pq->wPaintCount, pq->hSendingTask, pq->wTimerCount,
              pq->hPrevSendingTask, pq->wakeBits, pq->wakeMask, pq->hCurHook);
+
+    QUEUE_Unlock( pq );
 }
 
 
@@ -77,7 +129,7 @@
     DUMP( "Queue Msgs Thread   Task Module\n" );
     while (hQueue)
     {
-        MESSAGEQUEUE *queue = (MESSAGEQUEUE *)GlobalLock16( hQueue );
+        MESSAGEQUEUE *queue = (MESSAGEQUEUE *)QUEUE_Lock( hQueue );
         if (!queue)
         {
             WARN( msg, "Bad queue handle %04x\n", hQueue );
@@ -88,6 +140,7 @@
         DUMP( "%04x %4d %p %04x %s\n", hQueue,queue->msgCount,
               queue->thdb, queue->thdb->process->task, module );
         hQueue = queue->next;
+        QUEUE_Unlock( queue );
     }
     DUMP( "\n" );
 }
@@ -126,15 +179,20 @@
 
     if (!(hQueue = GlobalAlloc16( GMEM_FIXED | GMEM_ZEROINIT,
                                   sizeof(MESSAGEQUEUE) )))
-    {
         return 0;
-    }
 
     msgQueue = (MESSAGEQUEUE *) GlobalLock16( hQueue );
-    InitializeCriticalSection( &msgQueue->cSection );
+    if ( !msgQueue )
+        return 0;
+
     msgQueue->self        = hQueue;
     msgQueue->wakeBits    = msgQueue->changeBits = QS_SMPARAMSFREE;
     msgQueue->wWinVersion = pTask ? pTask->version : 0;
+    
+    InitializeCriticalSection( &msgQueue->cSection );
+    msgQueue->lockCount = 1;
+    msgQueue->magic = QUEUE_MAGIC;
+    
     return hQueue;
 }
 
@@ -149,7 +207,7 @@
  */
 BOOL32 QUEUE_DeleteMsgQueue( HQUEUE16 hQueue )
 {
-    MESSAGEQUEUE * msgQueue = (MESSAGEQUEUE*)GlobalLock16(hQueue);
+    MESSAGEQUEUE * msgQueue = (MESSAGEQUEUE*)QUEUE_Lock(hQueue);
     HQUEUE16  senderQ;
     HQUEUE16 *pPrev;
 
@@ -160,22 +218,27 @@
 	WARN(msg, "invalid argument.\n");
 	return 0;
     }
-    if( pCursorQueue == msgQueue ) pCursorQueue = NULL;
-    if( pActiveQueue == msgQueue ) pActiveQueue = NULL;
+
+    msgQueue->magic = 0;
+    
+    if( hCursorQueue == hQueue ) hCursorQueue = 0;
+    if( hActiveQueue == hQueue ) hActiveQueue = 0;
 
     /* flush sent messages */
     senderQ = msgQueue->hSendingTask;
     while( senderQ )
     {
-      MESSAGEQUEUE* sq = (MESSAGEQUEUE*)GlobalLock16(senderQ);
+      MESSAGEQUEUE* sq = (MESSAGEQUEUE*)QUEUE_Lock(senderQ);
       if( !sq ) break;
       sq->SendMessageReturn = 0L;
       QUEUE_SetWakeBit( sq, QS_SMRESULT );
       senderQ = sq->hPrevSendingTask;
+      QUEUE_Unlock(sq);
     }
 
-    SIGNAL_MaskAsyncEvents( TRUE );
+    SYSTEM_LOCK();
 
+    /* remove the message queue from the global link list */
     pPrev = &hFirstQueue;
     while (*pPrev && (*pPrev != hQueue))
     {
@@ -185,9 +248,12 @@
     if (*pPrev) *pPrev = msgQueue->next;
     msgQueue->self = 0;
 
-    SIGNAL_MaskAsyncEvents( FALSE );
+    SYSTEM_UNLOCK();
 
-    GlobalFree16( hQueue );
+    /* free up resource used by MESSAGEQUEUE strcture */
+    msgQueue->lockCount--;
+    QUEUE_Unlock( msgQueue );
+    
     return 1;
 }
 
@@ -285,12 +351,13 @@
 
     for (;;)
     {
-        if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetFastQueue() ))) return;
+        if (!(queue = (MESSAGEQUEUE *)QUEUE_Lock( GetFastQueue() ))) return;
 
         if (queue->changeBits & bits)
         {
             /* One of the bits is set; we can return */
             queue->wakeMask = 0;
+            QUEUE_Unlock( queue );
             return;
         }
         if (queue->wakeBits & QS_SENDMESSAGE)
@@ -299,15 +366,22 @@
 
 	    queue->wakeMask = 0;
             QUEUE_ReceiveMessage( queue );
+            QUEUE_Unlock( queue );
 	    continue;				/* nested sm crux */
         }
 
         queue->wakeMask = bits | QS_SENDMESSAGE;
-	if(queue->changeBits & bits) continue;
+        if(queue->changeBits & bits)
+        {
+            QUEUE_Unlock( queue );
+            continue;
+        }
 	
 	TRACE(msg,"%04x) wakeMask is %04x, waiting\n", queue->self, queue->wakeMask);
 
         QUEUE_Wait( queue->wakeMask );
+
+        QUEUE_Unlock( queue );
     }
 }
 
@@ -326,7 +400,7 @@
 
     TRACE(msg, "ReceiveMessage, queue %04x\n", queue->self );
     if (!(queue->wakeBits & QS_SENDMESSAGE) ||
-        !(senderQ = (MESSAGEQUEUE*)GlobalLock16( queue->hSendingTask))) 
+        !(senderQ = (MESSAGEQUEUE*)QUEUE_Lock( queue->hSendingTask)))
 	{ TRACE(msg,"\trcm: nothing to do\n"); return; }
 
     if( !senderQ->hPrevSendingTask )
@@ -379,6 +453,8 @@
     }
     else WARN(msg, "\trcm: bad hWnd\n");
 
+    QUEUE_Unlock( senderQ );
+    
     /* Return the result to the sender task */
     ReplyMessage16( result );
 
@@ -395,11 +471,11 @@
  */
 void QUEUE_FlushMessages( HQUEUE16 hQueue )
 {
-  MESSAGEQUEUE *queue = (MESSAGEQUEUE*)GlobalLock16( hQueue );
+  MESSAGEQUEUE *queue = (MESSAGEQUEUE*)QUEUE_Lock( hQueue );
 
   if( queue )
   {
-    MESSAGEQUEUE *senderQ = (MESSAGEQUEUE*)GlobalLock16( queue->hSendingTask);
+    MESSAGEQUEUE *senderQ = (MESSAGEQUEUE*)QUEUE_Lock( queue->hSendingTask );
     QSMCTRL*      CtrlPtr = queue->smResultCurrent;
 
     TRACE(msg,"Flushing queue %04x:\n", hQueue );
@@ -423,11 +499,16 @@
       senderQ->smResult = queue->smResultCurrent;
       QUEUE_SetWakeBit( senderQ, QS_SMRESULT);
 
-      senderQ = (MESSAGEQUEUE*)GlobalLock16( queue->hSendingTask);
+      QUEUE_Unlock( senderQ );
+
+      senderQ = (MESSAGEQUEUE*)QUEUE_Lock( queue->hSendingTask );
       CtrlPtr = NULL;
     }
     queue->InSendMessageHandle = 0;
+    
+    QUEUE_Unlock( queue );
   }  
+
 }
 
 /***********************************************************************
@@ -441,11 +522,14 @@
     QMSG         *qmsg;
 
 
-    if (!(msgQueue = (MESSAGEQUEUE *)GlobalLock16( hQueue ))) return FALSE;
+    if (!(msgQueue = (MESSAGEQUEUE *)QUEUE_Lock( hQueue ))) return FALSE;
 
     /* allocate new message in global heap for now */
     if (!(qmsg = (QMSG *) HeapAlloc( SystemHeap, 0, sizeof(QMSG) ) ))
+    {
+        QUEUE_Unlock( msgQueue );
         return 0;
+    }
 
     EnterCriticalSection( &msgQueue->cSection );
 
@@ -470,6 +554,8 @@
     LeaveCriticalSection( &msgQueue->cSection );
 
     QUEUE_SetWakeBit( msgQueue, QS_POSTMESSAGE );
+    QUEUE_Unlock( msgQueue );
+    
     return TRUE;
 }
 
@@ -557,32 +643,46 @@
     WND*	  wndPtr = NULL;
     WORD          wakeBit;
     HWND32 hwnd;
-    MESSAGEQUEUE *queue = pCursorQueue;
+    HQUEUE16     hQueue = 0;
+    MESSAGEQUEUE *queue = NULL;
+
+    if (hCursorQueue)
+        hQueue = hCursorQueue;
 
     if( (message >= WM_KEYFIRST) && (message <= WM_KEYLAST) )
     {
        wakeBit = QS_KEY;
-       if( pActiveQueue ) queue = pActiveQueue;
+       if( hActiveQueue )
+           hQueue = hActiveQueue;
     }
     else 
     {
        wakeBit = (message == WM_MOUSEMOVE) ? QS_MOUSEMOVE : QS_MOUSEBUTTON;
        if( (hwnd = GetCapture32()) )
 	 if( (wndPtr = WIN_FindWndPtr( hwnd )) ) 
-	   queue = (MESSAGEQUEUE *)GlobalLock16( wndPtr->hmemTaskQ );
+           {
+               hQueue = wndPtr->hmemTaskQ;
+           }
     }
 
     if( (hwnd = GetSysModalWindow16()) )
+    {
       if( (wndPtr = WIN_FindWndPtr( hwnd )) )
-        queue = (MESSAGEQUEUE *)GlobalLock16( wndPtr->hmemTaskQ );
+            hQueue = wndPtr->hmemTaskQ;
+    }
 
+    if (hQueue)
+        queue = QUEUE_Lock( hQueue );
+    
     if( !queue ) 
     {
-      queue = GlobalLock16( hFirstQueue );
+        queue = QUEUE_Lock( hFirstQueue );
       while( queue )
       {
         if (queue->wakeMask & wakeBit) break;
-        queue = GlobalLock16( queue->next );
+          
+            QUEUE_Unlock(queue);
+            queue = QUEUE_Lock( queue->next );
       }
       if( !queue )
       { 
@@ -592,6 +692,8 @@
     }
 
     QUEUE_SetWakeBit( queue, wakeBit );
+
+    QUEUE_Unlock( queue );
 }
 
 
@@ -669,10 +771,20 @@
  */
 HTASK16 QUEUE_GetQueueTask( HQUEUE16 hQueue )
 {
-    MESSAGEQUEUE *queue = GlobalLock16( hQueue );
-    return (queue) ? queue->thdb->process->task : 0 ;
+    HTASK16 hTask = 0;
+    
+    MESSAGEQUEUE *queue = QUEUE_Lock( hQueue );
+
+    if (queue)
+{
+        hTask = queue->thdb->process->task;
+        QUEUE_Unlock( queue );
 }
 
+    return hTask;
+}
+
+
 
 /***********************************************************************
  *           QUEUE_IncPaintCount
@@ -681,9 +793,10 @@
 {
     MESSAGEQUEUE *queue;
 
-    if (!(queue = (MESSAGEQUEUE *)GlobalLock16( hQueue ))) return;
+    if (!(queue = (MESSAGEQUEUE *)QUEUE_Lock( hQueue ))) return;
     queue->wPaintCount++;
     QUEUE_SetWakeBit( queue, QS_PAINT );
+    QUEUE_Unlock( queue );
 }
 
 
@@ -694,9 +807,10 @@
 {
     MESSAGEQUEUE *queue;
 
-    if (!(queue = (MESSAGEQUEUE *)GlobalLock16( hQueue ))) return;
+    if (!(queue = (MESSAGEQUEUE *)QUEUE_Lock( hQueue ))) return;
     queue->wPaintCount--;
     if (!queue->wPaintCount) queue->wakeBits &= ~QS_PAINT;
+    QUEUE_Unlock( queue );
 }
 
 
@@ -707,9 +821,10 @@
 {
     MESSAGEQUEUE *queue;
 
-    if (!(queue = (MESSAGEQUEUE *)GlobalLock16( hQueue ))) return;
+    if (!(queue = (MESSAGEQUEUE *)QUEUE_Lock( hQueue ))) return;
     queue->wTimerCount++;
     QUEUE_SetWakeBit( queue, QS_TIMER );
+    QUEUE_Unlock( queue );
 }
 
 
@@ -720,9 +835,10 @@
 {
     MESSAGEQUEUE *queue;
 
-    if (!(queue = (MESSAGEQUEUE *)GlobalLock16( hQueue ))) return;
+    if (!(queue = (MESSAGEQUEUE *)QUEUE_Lock( hQueue ))) return;
     queue->wTimerCount--;
     if (!queue->wTimerCount) queue->wakeBits &= ~QS_TIMER;
+    QUEUE_Unlock( queue );
 }
 
 
@@ -753,9 +869,10 @@
 {
     MESSAGEQUEUE *queue;
 
-    if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetFastQueue() ))) return;
+    if (!(queue = (MESSAGEQUEUE *)QUEUE_Lock( GetFastQueue() ))) return;
     queue->wPostQMsg = TRUE;
     queue->wExitCode = (WORD)exitCode;
+    QUEUE_Unlock( queue );
 }
 
 
@@ -837,16 +954,18 @@
     }
         
         /* Link new queue into list */
-        queuePtr = (MESSAGEQUEUE *)GlobalLock16( hQueue );
+        queuePtr = (MESSAGEQUEUE *)QUEUE_Lock( hQueue );
         queuePtr->thdb = THREAD_Current();
 
-        SIGNAL_MaskAsyncEvents( TRUE );
+        SYSTEM_LOCK();
         SetThreadQueue( 0, hQueue );
         thdb->teb.queue = hQueue;
             
         queuePtr->next  = hFirstQueue;
         hFirstQueue = hQueue;
-        SIGNAL_MaskAsyncEvents( FALSE );
+        SYSTEM_UNLOCK();
+        
+        QUEUE_Unlock( queuePtr );
     }
 
     return hQueue;
@@ -860,9 +979,11 @@
     MESSAGEQUEUE *queue;
     DWORD ret;
 
-    if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetFastQueue() ))) return 0;
+    if (!(queue = (MESSAGEQUEUE *)QUEUE_Lock( GetFastQueue() ))) return 0;
     ret = MAKELONG( queue->changeBits, queue->wakeBits );
     queue->changeBits = 0;
+    QUEUE_Unlock( queue );
+    
     return ret & MAKELONG( flags, flags );
 }
 
@@ -874,9 +995,11 @@
     MESSAGEQUEUE *queue;
     DWORD ret;
 
-    if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetFastQueue() ))) return 0;
+    if (!(queue = (MESSAGEQUEUE *)QUEUE_Lock( GetFastQueue() ))) return 0;
     ret = MAKELONG( queue->changeBits, queue->wakeBits );
     queue->changeBits = 0;
+    QUEUE_Unlock( queue );
+    
     return ret & MAKELONG( flags, flags );
 }
 
@@ -906,10 +1029,14 @@
 BOOL32 WINAPI GetInputState32(void)
 {
     MESSAGEQUEUE *queue;
+    BOOL32 ret;
 
-    if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetFastQueue() )))
+    if (!(queue = (MESSAGEQUEUE *)QUEUE_Lock( GetFastQueue() )))
         return FALSE;
-    return queue->wakeBits & (QS_KEY | QS_MOUSEBUTTON);
+    ret = queue->wakeBits & (QS_KEY | QS_MOUSEBUTTON);
+    QUEUE_Unlock( queue );
+
+    return ret;
 }
 
 /***********************************************************************
@@ -918,11 +1045,12 @@
 void WINAPI UserYield(void)
 {
     TDB *pCurTask = (TDB *)GlobalLock16( GetCurrentTask() );
-    MESSAGEQUEUE *queue = (MESSAGEQUEUE *)GlobalLock16( pCurTask->hQueue );
+    MESSAGEQUEUE *queue = (MESSAGEQUEUE *)QUEUE_Lock( pCurTask->hQueue );
 
     if ( !THREAD_IsWin16( THREAD_Current() ) )
     {
         FIXME(task, "called for Win32 thread (%04x)!\n", THREAD_Current()->teb_sel);
+        QUEUE_Unlock( queue );
         return;
     }
 
@@ -930,11 +1058,15 @@
     while (queue && (queue->wakeBits & QS_SENDMESSAGE))
         QUEUE_ReceiveMessage( queue );
 
+    QUEUE_Unlock( queue );
+    
     OldYield();
 
-    queue = (MESSAGEQUEUE *)GlobalLock16( pCurTask->hQueue );
+    queue = (MESSAGEQUEUE *)QUEUE_Lock( pCurTask->hQueue );
     while (queue && (queue->wakeBits & QS_SENDMESSAGE))
         QUEUE_ReceiveMessage( queue );
+
+    QUEUE_Unlock( queue );
 }
 
 /***********************************************************************
@@ -961,9 +1093,13 @@
 DWORD WINAPI GetMessagePos(void)
 {
     MESSAGEQUEUE *queue;
+    DWORD ret;
 
-    if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetFastQueue() ))) return 0;
-    return queue->GetMessagePosVal;
+    if (!(queue = (MESSAGEQUEUE *)QUEUE_Lock( GetFastQueue() ))) return 0;
+    ret = queue->GetMessagePosVal;
+    QUEUE_Unlock( queue );
+
+    return ret;
 }
 
 
@@ -989,9 +1125,13 @@
 LONG WINAPI GetMessageTime(void)
 {
     MESSAGEQUEUE *queue;
+    LONG ret;
 
-    if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetFastQueue() ))) return 0;
-    return queue->GetMessageTimeVal;
+    if (!(queue = (MESSAGEQUEUE *)QUEUE_Lock( GetFastQueue() ))) return 0;
+    ret = queue->GetMessageTimeVal;
+    QUEUE_Unlock( queue );
+    
+    return ret;
 }
 
 
@@ -1001,7 +1141,11 @@
 LONG WINAPI GetMessageExtraInfo(void)
 {
     MESSAGEQUEUE *queue;
+    LONG ret;
 
-    if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetFastQueue() ))) return 0;
-    return queue->GetMessageExtraInfoVal;
+    if (!(queue = (MESSAGEQUEUE *)QUEUE_Lock( GetFastQueue() ))) return 0;
+    ret = queue->GetMessageExtraInfoVal;
+    QUEUE_Unlock( queue );
+
+    return ret;
 }
diff --git a/windows/win.c b/windows/win.c
index 05e0d67..e583f0c 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -294,7 +294,7 @@
     {
 	BOOL32	      bPostQuit = FALSE;
 	WPARAM32      wQuitParam = 0;
-        MESSAGEQUEUE* msgQ = (MESSAGEQUEUE*) GlobalLock16(wndPtr->hmemTaskQ);
+        MESSAGEQUEUE* msgQ = (MESSAGEQUEUE*) QUEUE_Lock(wndPtr->hmemTaskQ);
         QMSG *qmsg;
 
 	while( (qmsg = QUEUE_FindMsg(msgQ, hwnd, 0, 0)) != 0 )
@@ -306,6 +306,9 @@
 	    }
 	    QUEUE_RemoveMsg(msgQ, qmsg);
 	}
+
+        QUEUE_Unlock(msgQ);
+        
 	/* repost WM_QUIT to make sure this app exits its message loop */
 	if( bPostQuit ) PostQuitMessage32(wQuitParam);
 	wndPtr->hmemTaskQ = 0;
diff --git a/windows/winpos.c b/windows/winpos.c
index 2593483..33b191b 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -56,7 +56,7 @@
 
 static LPCSTR atomInternalPos;
 
-extern MESSAGEQUEUE* pActiveQueue;
+extern HQUEUE16 hActiveQueue;
 
 /***********************************************************************
  *           WINPOS_CreateInternalPosAtom
@@ -1461,7 +1461,7 @@
  *	return 0;
  */
     wndPtr = WIN_FindWndPtr(hWnd);
-    hOldActiveQueue = (pActiveQueue)?pActiveQueue->self : 0;
+    hOldActiveQueue = hActiveQueue;
 
     if( (wndTemp = WIN_FindWndPtr(hwndActive)) )
 	wIconized = HIWORD(wndTemp->dwStyle & WS_MINIMIZE);
@@ -1547,8 +1547,7 @@
             HeapFree( SystemHeap, 0, list );
         }
 
-	pActiveQueue = (hNewActiveQueue)
-		       ? (MESSAGEQUEUE*) GlobalLock16(hNewActiveQueue) : NULL;
+	hActiveQueue = hNewActiveQueue;
 
         if ((list = WIN_BuildWinArray( WIN_GetDesktop(), 0, NULL )))
         {
@@ -1562,6 +1561,7 @@
             }
             HeapFree( SystemHeap, 0, list );
         }
+        
 	if (!IsWindow32(hWnd)) return 0;
     }