- 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/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;
}
/***********************************************************************