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