Fixed some bugs in thread safeness for wnd struct.
diff --git a/windows/message.c b/windows/message.c
index 5131bce..f4e92e8 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -64,17 +64,23 @@
#define lppt ((LPPOINT16)&lValue)
/* pt has to be in the client coordinates of the parent window */
+ WND *tmpWnd = WIN_LockWndPtr(wndPtr);
- MapWindowPoints16( 0, wndPtr->hwndSelf, lppt, 1 );
- while (wndPtr)
+ MapWindowPoints16( 0, tmpWnd->hwndSelf, lppt, 1 );
+ while (tmpWnd)
{
- if (!(wndPtr->dwStyle & WS_CHILD) || (wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY)) break;
- lppt->x += wndPtr->rectClient.left;
- lppt->y += wndPtr->rectClient.top;
- wndPtr = wndPtr->parent;
- SendMessageA( wndPtr->hwndSelf, WM_PARENTNOTIFY,
+ if (!(tmpWnd->dwStyle & WS_CHILD) || (tmpWnd->dwExStyle & WS_EX_NOPARENTNOTIFY))
+ {
+ WIN_ReleaseWndPtr(tmpWnd);
+ break;
+ }
+ lppt->x += tmpWnd->rectClient.left;
+ lppt->y += tmpWnd->rectClient.top;
+ WIN_UpdateWndPtr(&tmpWnd,tmpWnd->parent);
+ SendMessageA( tmpWnd->hwndSelf, WM_PARENTNOTIFY,
MAKEWPARAM( event, idChild ), lValue );
}
+
#undef lppt
}
@@ -107,6 +113,7 @@
(message == WM_RBUTTONDOWN) ||
(message == WM_MBUTTONDOWN))?1:0;
SYSQ_STATUS ret = 0;
+ DWORD retvalue;
/* Find the window */
@@ -118,6 +125,7 @@
{
ht = hittest = WINPOS_WindowFromPoint( pWndScope, pt, &pWnd );
if( !pWnd ) pWnd = WIN_GetDesktop();
+ else WIN_LockWndPtr(pWnd);
hWnd = pWnd->hwndSelf;
sendSC = 1;
}
@@ -140,7 +148,8 @@
if (queue) QUEUE_SetWakeBit( queue, QS_MOUSE );
QUEUE_Unlock( queue );
- return SYSQ_MSG_ABANDON;
+ retvalue = SYSQ_MSG_ABANDON;
+ goto END;
}
/* check if hWnd is within hWndScope */
@@ -149,7 +158,8 @@
if( !IsChild(hTopWnd, hWnd) )
{
QUEUE_Unlock( queue );
- return SYSQ_MSG_CONTINUE;
+ retvalue = SYSQ_MSG_CONTINUE;
+ goto END;
}
if( mouseClick )
@@ -184,12 +194,14 @@
if (!MSG_CheckFilter(message, first, last))
{
QUEUE_Unlock(queue);
- return SYSQ_MSG_CONTINUE;
+ retvalue = SYSQ_MSG_CONTINUE;
+ goto END;
}
hCursorQueue = queue->self;
QUEUE_Unlock(queue);
+
/* call WH_MOUSE */
if (HOOK_IsHooked( WH_MOUSE ))
@@ -205,9 +217,15 @@
message, (LPARAM)SEGPTR_GET(hook) );
SEGPTR_FREE(hook);
}
- if( ret ) return MAKELONG((INT16)SYSQ_MSG_SKIP, hittest);
+ if( ret )
+ {
+ retvalue = MAKELONG((INT16)SYSQ_MSG_SKIP, hittest);
+ goto END;
}
+ }
+
+
if ((hittest == HTERROR) || (hittest == HTNOWHERE))
eatMsg = sendSC = 1;
else if( remove && mouseClick )
@@ -257,12 +275,20 @@
if (sendSC)
SendMessageA( hWnd, WM_SETCURSOR, hWnd,
MAKELONG( hittest, message ));
- if (eatMsg) return MAKELONG( (UINT16)SYSQ_MSG_SKIP, hittest);
+ if (eatMsg)
+ {
+ retvalue = MAKELONG( (UINT16)SYSQ_MSG_SKIP, hittest);
+ goto END;
+ }
msg->hwnd = hWnd;
msg->message = message;
msg->lParam = MAKELONG( pt.x, pt.y );
- return SYSQ_MSG_ACCEPT;
+ retvalue = SYSQ_MSG_ACCEPT;
+END:
+ WIN_ReleaseWndPtr(pWnd);
+
+ return retvalue;
}
@@ -302,8 +328,10 @@
queue = (MESSAGEQUEUE *)QUEUE_Lock( pWnd->hmemTaskQ );
if (queue) QUEUE_SetWakeBit( queue, QS_KEY );
QUEUE_Unlock( queue );
+ WIN_ReleaseWndPtr(pWnd);
return SYSQ_MSG_ABANDON;
}
+ WIN_ReleaseWndPtr(pWnd);
if (hTopWnd && hWnd != hTopWnd)
if (!IsChild(hTopWnd, hWnd)) return SYSQ_MSG_CONTINUE;
@@ -490,12 +518,16 @@
if ((msg->message >= WM_MOUSEFIRST) && (msg->message <= WM_MOUSELAST))
{
- HWND hWndScope = (HWND)qmsg->extraInfo;
- status = MSG_TranslateMouseMsg(hwnd, first, last, msg, remove,
- (Options.managed && IsWindow(hWndScope) )
- ? WIN_FindWndPtr(hWndScope) : WIN_GetDesktop() );
+ HWND hWndScope = (HWND)qmsg->extraInfo;
+ WND *tmpWnd = (Options.managed && IsWindow(hWndScope) )
+ ? WIN_FindWndPtr(hWndScope) : WIN_GetDesktop();
+
+ status = MSG_TranslateMouseMsg(hwnd, first, last, msg, remove,tmpWnd );
kbd_msg = 0;
+
+ WIN_ReleaseWndPtr(tmpWnd);
+
}
else if ((msg->message >= WM_KEYFIRST) && (msg->message <= WM_KEYLAST))
{
@@ -631,6 +663,7 @@
MESSAGEQUEUE *queue, *destQ;
SMSG *smsg;
LRESULT retVal = 1;
+ int iWndsLocks;
*pRes = 0;
@@ -669,6 +702,8 @@
if (QUEUE_AddSMSG(destQ, SM_PENDING_LIST, smsg) == FALSE)
return 0;
+ iWndsLocks = WIN_SuspendWndsLock();
+
/* force destination task to run next, if 16 bit threads */
if ( THREAD_IsWin16(THREAD_Current()) && THREAD_IsWin16(destQ->thdb) )
DirectedYield16( destQ->thdb->teb.htask16 );
@@ -710,6 +745,7 @@
break;
}
}
+ WIN_RestoreWndsLock(iWndsLocks);
/* remove the smsg from the processingg list of the source queue */
QUEUE_RemoveSMSG( queue, SM_PROCESSING_LIST, smsg );
@@ -758,10 +794,12 @@
SMSG *smsg;
BOOL ret = FALSE;
- if (!(queue = (MESSAGEQUEUE*)QUEUE_Lock( GetFastQueue16() ))) return FALSE;
+ if (!(queue = (MESSAGEQUEUE*)QUEUE_Lock( GetFastQueue16() )))
+ return FALSE;
TRACE(sendmsg,"ReplyMessage, queue %04x\n", queue->self);
+
if ( !(smsg = queue->smWaiting)
|| !(senderQ = QUEUE_Lock( smsg->hSrcQueue )) )
goto ReplyMessageEnd;
@@ -838,6 +876,7 @@
MESSAGEQUEUE *msgQueue;
HQUEUE16 hQueue;
POINT16 pt16;
+ int iWndsLocks;
#ifdef CONFIG_IPC
DDE_TestDDE(hwnd); /* do we have dde handling in the window ?*/
@@ -861,13 +900,19 @@
/* Never yield on Win32 threads */
if (!THREAD_IsWin16(THREAD_Current())) flags |= PM_NOYIELD;
+ iWndsLocks = WIN_SuspendWndsLock();
+
while(1)
{
QMSG *qmsg;
hQueue = GetFastQueue16();
msgQueue = (MESSAGEQUEUE *)QUEUE_Lock( hQueue );
- if (!msgQueue) return FALSE;
+ if (!msgQueue)
+ {
+ WIN_RestoreWndsLock(iWndsLocks);
+ return FALSE;
+ }
msgQueue->changeBits = 0;
/* First handle a message put by SendMessage() */
@@ -951,8 +996,10 @@
wndPtr->flags &= ~WIN_INTERNAL_PAINT;
QUEUE_DecPaintCount( hQueue );
}
+ WIN_ReleaseWndPtr(wndPtr);
break;
}
+ WIN_ReleaseWndPtr(wndPtr);
}
}
@@ -974,6 +1021,7 @@
if (!(flags & PM_NOYIELD)) UserYield16();
QUEUE_Unlock( msgQueue );
+ WIN_RestoreWndsLock(iWndsLocks);
return FALSE;
}
msgQueue->wakeMask = mask;
@@ -981,6 +1029,8 @@
QUEUE_Unlock( msgQueue );
}
+ WIN_RestoreWndsLock(iWndsLocks);
+
/* instead of unlocking queue for every break condition, all break
condition will fall here */
QUEUE_Unlock( msgQueue );
@@ -1001,8 +1051,12 @@
else if (message == WM_KEYUP || message == WM_SYSKEYUP)
QueueKeyStateTable[msg->wParam & 0xff] &= ~0x80;
}
- if (peek) return TRUE;
- else return (msg->message != WM_QUIT);
+
+ if (peek)
+ return TRUE;
+
+ else
+ return (msg->message != WM_QUIT);
}
/***********************************************************************
@@ -1277,6 +1331,7 @@
{
MSG msg;
WND *wndPtr;
+ BOOL retvalue;
msg.hwnd = hwnd;
msg.message = message;
@@ -1293,8 +1348,10 @@
if (hwnd == HWND_BROADCAST)
{
+ WND *pDesktop = WIN_GetDesktop();
TRACE(msg,"HWND_BROADCAST !\n");
- for (wndPtr = WIN_GetDesktop()->child; wndPtr; wndPtr = wndPtr->next)
+
+ for (wndPtr=WIN_LockWndPtr(pDesktop->child); wndPtr; WIN_UpdateWndPtr(&wndPtr,wndPtr->next))
{
if (wndPtr->dwStyle & WS_POPUP || wndPtr->dwStyle & WS_CAPTION)
{
@@ -1303,14 +1360,22 @@
PostMessageA( wndPtr->hwndSelf, message, wParam, lParam );
}
}
+ WIN_ReleaseDesktop();
TRACE(msg,"End of HWND_BROADCAST !\n");
return TRUE;
}
wndPtr = WIN_FindWndPtr( hwnd );
- if (!wndPtr || !wndPtr->hmemTaskQ) return FALSE;
+ if (!wndPtr || !wndPtr->hmemTaskQ)
+ {
+ retvalue = FALSE;
+ goto END;
+ }
- return QUEUE_AddMsg( wndPtr->hmemTaskQ, &msg, 0 );
+ retvalue = QUEUE_AddMsg( wndPtr->hmemTaskQ, &msg, 0 );
+END:
+ WIN_ReleaseWndPtr(wndPtr);
+ return retvalue;
}
@@ -1377,7 +1442,7 @@
LPARAM lParam, DWORD timeout, WORD flags,
LRESULT *pRes)
{
- WND * wndPtr;
+ WND * wndPtr = 0;
WND **list, **ppWnd;
LRESULT ret = 1;
@@ -1388,11 +1453,16 @@
*pRes = 1;
if (!(list = WIN_BuildWinArray( WIN_GetDesktop(), 0, NULL )))
+ {
+ WIN_ReleaseDesktop();
return 1;
+ }
+ WIN_ReleaseDesktop();
+
TRACE(msg,"HWND_BROADCAST !\n");
for (ppWnd = list; *ppWnd; ppWnd++)
{
- wndPtr = *ppWnd;
+ WIN_UpdateWndPtr(&wndPtr,*ppWnd);
if (!IsWindow(wndPtr->hwndSelf)) continue;
if (wndPtr->dwStyle & WS_POPUP || wndPtr->dwStyle & WS_CAPTION)
{
@@ -1402,7 +1472,8 @@
timeout, flags, pRes);
}
}
- HeapFree( SystemHeap, 0, list );
+ WIN_ReleaseWndPtr(wndPtr);
+ WIN_ReleaseWinArray(list);
TRACE(msg,"End of HWND_BROADCAST !\n");
return 1;
}
@@ -1440,8 +1511,10 @@
return 0;
}
if (QUEUE_IsExitingQueue(wndPtr->hmemTaskQ))
- return 0; /* Don't send anything if the task is dying */
-
+ {
+ ret = 0; /* Don't send anything if the task is dying */
+ goto END;
+ }
if (flags & SMSG_WIN32)
SPY_EnterMessage( SPY_SENDMESSAGE, hwnd, msg, wParam, lParam );
else
@@ -1469,7 +1542,8 @@
SPY_ExitMessage( SPY_RESULT_OK, hwnd, msg, ret );
else
SPY_ExitMessage( SPY_RESULT_OK16, hwnd, msg, ret );
-
+END:
+ WIN_ReleaseWndPtr(wndPtr);
return ret;
}
@@ -2005,7 +2079,11 @@
if (!msg->hwnd) return 0;
if (!(wndPtr = WIN_FindWndPtr( msg->hwnd ))) return 0;
- if (!wndPtr->winproc) return 0;
+ if (!wndPtr->winproc)
+ {
+ retval = 0;
+ goto END;
+ }
painting = (msg->message == WM_PAINT);
if (painting) wndPtr->flags |= WIN_NEEDS_BEGINPAINT;
@@ -2016,7 +2094,9 @@
msg->wParam, msg->lParam );
SPY_ExitMessage( SPY_RESULT_OK16, msg->hwnd, msg->message, retval );
- if (painting && (wndPtr = WIN_FindWndPtr( msg->hwnd )) &&
+ WIN_ReleaseWndPtr(wndPtr);
+ wndPtr = WIN_FindWndPtr(msg->hwnd);
+ if (painting && wndPtr &&
(wndPtr->flags & WIN_NEEDS_BEGINPAINT) && wndPtr->hrgnUpdate)
{
ERR(msg, "BeginPaint not called on WM_PAINT for hwnd %04x!\n",
@@ -2025,6 +2105,8 @@
/* Validate the update region to avoid infinite WM_PAINT loop */
ValidateRect( msg->hwnd, NULL );
}
+END:
+ WIN_ReleaseWndPtr(wndPtr);
return retval;
}
@@ -2073,7 +2155,11 @@
if (!msg->hwnd) return 0;
if (!(wndPtr = WIN_FindWndPtr( msg->hwnd ))) return 0;
- if (!wndPtr->winproc) return 0;
+ if (!wndPtr->winproc)
+ {
+ retval = 0;
+ goto END;
+ }
painting = (msg->message == WM_PAINT);
if (painting) wndPtr->flags |= WIN_NEEDS_BEGINPAINT;
/* HOOK_CallHooks32A( WH_CALLWNDPROC, HC_ACTION, 0, FIXME ); */
@@ -2085,7 +2171,10 @@
msg->wParam, msg->lParam );
SPY_ExitMessage( SPY_RESULT_OK, msg->hwnd, msg->message, retval );
- if (painting && (wndPtr = WIN_FindWndPtr( msg->hwnd )) &&
+ WIN_ReleaseWndPtr(wndPtr);
+ wndPtr = WIN_FindWndPtr(msg->hwnd);
+
+ if (painting && wndPtr &&
(wndPtr->flags & WIN_NEEDS_BEGINPAINT) && wndPtr->hrgnUpdate)
{
ERR(msg, "BeginPaint not called on WM_PAINT for hwnd %04x!\n",
@@ -2094,6 +2183,8 @@
/* Validate the update region to avoid infinite WM_PAINT loop */
ValidateRect( msg->hwnd, NULL );
}
+END:
+ WIN_ReleaseWndPtr(wndPtr);
return retval;
}
@@ -2138,7 +2229,11 @@
if (!msg->hwnd) return 0;
if (!(wndPtr = WIN_FindWndPtr( msg->hwnd ))) return 0;
- if (!wndPtr->winproc) return 0;
+ if (!wndPtr->winproc)
+ {
+ retval = 0;
+ goto END;
+ }
painting = (msg->message == WM_PAINT);
if (painting) wndPtr->flags |= WIN_NEEDS_BEGINPAINT;
/* HOOK_CallHooks32W( WH_CALLWNDPROC, HC_ACTION, 0, FIXME ); */
@@ -2150,7 +2245,10 @@
msg->wParam, msg->lParam );
SPY_ExitMessage( SPY_RESULT_OK, msg->hwnd, msg->message, retval );
- if (painting && (wndPtr = WIN_FindWndPtr( msg->hwnd )) &&
+ WIN_ReleaseWndPtr(wndPtr);
+ wndPtr = WIN_FindWndPtr(msg->hwnd);
+
+ if (painting && wndPtr &&
(wndPtr->flags & WIN_NEEDS_BEGINPAINT) && wndPtr->hrgnUpdate)
{
ERR(msg, "BeginPaint not called on WM_PAINT for hwnd %04x!\n",
@@ -2159,6 +2257,8 @@
/* Validate the update region to avoid infinite WM_PAINT loop */
ValidateRect( msg->hwnd, NULL );
}
+END:
+ WIN_ReleaseWndPtr(wndPtr);
return retval;
}