Commit 1c4786fe authored by Stephane Lussier's avatar Stephane Lussier Committed by Alexandre Julliard

- 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).
parent 03479f8a
......@@ -44,6 +44,9 @@ typedef struct tagMESSAGEQUEUE
HANDLE32 hEvent; /* Event handle */
CRITICAL_SECTION cSection; /* Queue access critical section */
DWORD magic; /* magic number should be QUEUE_MAGIC */
DWORD lockCount; /* reference counter */
WORD flags; /* Queue flags */
WORD wWinVersion; /* Expected Windows version */
......@@ -94,6 +97,10 @@ typedef struct tagMESSAGEQUEUE
#define QUEUE_SM_WIN32 0x0002 /* Currently sent message is Win32 */
#define QUEUE_SM_UNICODE 0x0004 /* Currently sent message is Unicode */
#define QUEUE_MAGIC 0xD46E80AF
extern MESSAGEQUEUE *QUEUE_Lock( HQUEUE16 hQueue );
extern void QUEUE_Unlock( MESSAGEQUEUE *queue );
extern void QUEUE_DumpQueue( HQUEUE16 hQueue );
extern void QUEUE_WalkQueues(void);
extern BOOL32 QUEUE_IsExitingQueue( HQUEUE16 hQueue );
......
......@@ -827,9 +827,11 @@ static HANDLE16 HOOK_GetHook( INT16 id, HQUEUE16 hQueue )
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 @@ static HHOOK HOOK_SetHook( INT16 id, LPVOID proc, INT32 type,
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 @@ static BOOL32 HOOK_RemoveHook( HANDLE16 hook )
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 @@ static LRESULT HOOK_CallHook( HANDLE16 hook, INT32 fromtype, INT32 code,
/* 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 @@ static LRESULT HOOK_CallHook( HANDLE16 hook, INT32 fromtype, INT32 code,
data->flags &= ~HOOK_INUSE;
queue->hCurHook = prevHook;
QUEUE_Unlock( queue );
if (UnMapFunc)
UnMapFunc( data->id, code, wParamOrig, lParamOrig, wParam, lParam );
......@@ -1089,7 +1095,7 @@ void HOOK_ResetQueueHooks( HQUEUE16 hQueue )
{
MESSAGEQUEUE *queue;
if ((queue = (MESSAGEQUEUE *)GlobalLock16( hQueue )) != NULL)
if ((queue = (MESSAGEQUEUE *)QUEUE_Lock( hQueue )) != NULL)
{
HOOKDATA* data;
HHOOK hook;
......@@ -1106,6 +1112,8 @@ void HOOK_ResetQueueHooks( HQUEUE16 hQueue )
} else break;
}
}
QUEUE_Unlock( queue );
}
}
......@@ -1329,9 +1337,12 @@ LRESULT WINAPI DefHookProc16( INT16 code, WPARAM16 wParam, LPARAM lParam,
/* 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;
}
......
......@@ -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 @@ static DWORD MSG_TranslateMouseMsg( HWND16 hTopWnd, DWORD filter,
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 @@ static DWORD MSG_TranslateMouseMsg( HWND16 hTopWnd, DWORD filter,
/* 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 @@ static DWORD MSG_TranslateMouseMsg( HWND16 hTopWnd, DWORD filter,
/* 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 @@ static DWORD MSG_TranslateKbdMsg( HWND16 hTopWnd, DWORD filter,
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 @@ static LRESULT MSG_SendMessage( HQUEUE16 hDestQueue, HWND16 hwnd, UINT16 msg,
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 (!(queue = (MESSAGEQUEUE*)QUEUE_Lock( GetFastQueue() ))) return 0;
if (IsTaskLocked() || !IsWindow32(hwnd)) 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 @@ static LRESULT MSG_SendMessage( HQUEUE16 hDestQueue, HWND16 hwnd, UINT16 msg,
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 @@ void WINAPI ReplyMessage16( LRESULT result )
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 @@ void WINAPI ReplyMessage16( LRESULT result )
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 @@ void WINAPI ReplyMessage16( LRESULT result )
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 @@ static BOOL32 MSG_PeekMessage( LPMSG16 msg, HWND16 hwnd, WORD first, WORD last,
QMSG *qmsg;
hQueue = GetFastQueue();
msgQueue = (MESSAGEQUEUE *)GlobalLock16( hQueue );
msgQueue = (MESSAGEQUEUE *)QUEUE_Lock( hQueue );
if (!msgQueue) return FALSE;
msgQueue->changeBits = 0;
......@@ -852,12 +886,19 @@ static BOOL32 MSG_PeekMessage( LPMSG16 msg, HWND16 hwnd, WORD first, WORD last,
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 @@ DWORD WINAPI MsgWaitForMultipleObjects( DWORD nCount, HANDLE32 *pHandles,
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 @@ BOOL16 WINAPI InSendMessage16(void)
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;
}
/***********************************************************************
......
......@@ -28,8 +28,58 @@ static MESSAGEQUEUE *sysMsgQueue = NULL;
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 @@ void QUEUE_DumpQueue( HQUEUE16 hQueue )
{
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 @@ void QUEUE_DumpQueue( HQUEUE16 hQueue )
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 @@ void QUEUE_WalkQueues(void)
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 @@ void QUEUE_WalkQueues(void)
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 @@ static HQUEUE16 QUEUE_CreateMsgQueue( )
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 @@ static HQUEUE16 QUEUE_CreateMsgQueue( )
*/
BOOL32 QUEUE_DeleteMsgQueue( HQUEUE16 hQueue )
{
MESSAGEQUEUE * msgQueue = (MESSAGEQUEUE*)GlobalLock16(hQueue);
MESSAGEQUEUE * msgQueue = (MESSAGEQUEUE*)QUEUE_Lock(hQueue);
HQUEUE16 senderQ;
HQUEUE16 *pPrev;
......@@ -160,22 +218,27 @@ BOOL32 QUEUE_DeleteMsgQueue( HQUEUE16 hQueue )
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 @@ BOOL32 QUEUE_DeleteMsgQueue( HQUEUE16 hQueue )
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 @@ void QUEUE_WaitBits( WORD bits )
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 @@ void QUEUE_WaitBits( WORD bits )
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 @@ void QUEUE_ReceiveMessage( MESSAGEQUEUE *queue )
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 @@ void QUEUE_ReceiveMessage( MESSAGEQUEUE *queue )
}
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_ReceiveMessage( MESSAGEQUEUE *queue )
*/
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 @@ void QUEUE_FlushMessages( HQUEUE16 hQueue )
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 @@ BOOL32 QUEUE_AddMsg( HQUEUE16 hQueue, MSG32 *msg, DWORD extraInfo )
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 @@ BOOL32 QUEUE_AddMsg( HQUEUE16 hQueue, MSG32 *msg, DWORD extraInfo )
LeaveCriticalSection( &msgQueue->cSection );
QUEUE_SetWakeBit( msgQueue, QS_POSTMESSAGE );
QUEUE_Unlock( msgQueue );
return TRUE;
}
......@@ -557,32 +643,46 @@ static void QUEUE_WakeSomeone( UINT32 message )
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 @@ static void QUEUE_WakeSomeone( UINT32 message )
}
QUEUE_SetWakeBit( queue, wakeBit );
QUEUE_Unlock( queue );
}
......@@ -669,10 +771,20 @@ void hardware_event( WORD message, WORD wParam, LONG lParam,
*/
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 @@ void QUEUE_IncPaintCount( HQUEUE16 hQueue )
{
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 @@ void QUEUE_DecPaintCount( HQUEUE16 hQueue )
{
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 @@ void QUEUE_IncTimerCount( HQUEUE16 hQueue )
{
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 @@ void QUEUE_DecTimerCount( HQUEUE16 hQueue )
{
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 @@ void WINAPI PostQuitMessage32( INT32 exitCode )
{
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 @@ HQUEUE16 WINAPI InitThreadInput( WORD unknown, WORD flags )
}
/* 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 @@ DWORD WINAPI GetQueueStatus16( UINT16 flags )
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 @@ DWORD WINAPI GetQueueStatus32( UINT32 flags )
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 @@ DWORD WINAPI WaitForInputIdle (HANDLE32 hProcess, DWORD dwTimeOut)
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 @@ BOOL32 WINAPI GetInputState32(void)
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 @@ void WINAPI UserYield(void)
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 @@ void WINAPI UserYield(void)
DWORD WINAPI GetMessagePos(void)
{
MESSAGEQUEUE *queue;
DWORD ret;
if (!(queue = (MESSAGEQUEUE *)QUEUE_Lock( GetFastQueue() ))) return 0;
ret = queue->GetMessagePosVal;
QUEUE_Unlock( queue );
if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetFastQueue() ))) return 0;
return queue->GetMessagePosVal;
return ret;
}
......@@ -989,9 +1125,13 @@ DWORD WINAPI GetMessagePos(void)
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 GetMessageTime(void)
LONG WINAPI GetMessageExtraInfo(void)
{
MESSAGEQUEUE *queue;
LONG ret;
if (!(queue = (MESSAGEQUEUE *)QUEUE_Lock( GetFastQueue() ))) return 0;
ret = queue->GetMessageExtraInfoVal;
QUEUE_Unlock( queue );
if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetFastQueue() ))) return 0;
return queue->GetMessageExtraInfoVal;
return ret;
}
......@@ -294,7 +294,7 @@ static WND* WIN_DestroyWindow( WND* wndPtr )
{
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 @@ static WND* WIN_DestroyWindow( WND* wndPtr )
}
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;
......
......@@ -56,7 +56,7 @@ static HWND32 hGlobalShellWindow=0; /*the shell*/
static LPCSTR atomInternalPos;
extern MESSAGEQUEUE* pActiveQueue;
extern HQUEUE16 hActiveQueue;
/***********************************************************************
* WINPOS_CreateInternalPosAtom
......@@ -1461,7 +1461,7 @@ BOOL32 WINPOS_SetActiveWindow( HWND32 hWnd, BOOL32 fMouse, BOOL32 fChangeFocus)
* 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 @@ BOOL32 WINPOS_SetActiveWindow( HWND32 hWnd, BOOL32 fMouse, BOOL32 fChangeFocus)
HeapFree( SystemHeap, 0, list );
}
pActiveQueue = (hNewActiveQueue)
? (MESSAGEQUEUE*) GlobalLock16(hNewActiveQueue) : NULL;
hActiveQueue = hNewActiveQueue;
if ((list = WIN_BuildWinArray( WIN_GetDesktop(), 0, NULL )))
{
......@@ -1562,6 +1561,7 @@ BOOL32 WINPOS_SetActiveWindow( HWND32 hWnd, BOOL32 fMouse, BOOL32 fChangeFocus)
}
HeapFree( SystemHeap, 0, list );
}
if (!IsWindow32(hWnd)) return 0;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment