Get rid of the window lock suspend mechanism.

This commit is contained in:
Alexandre Julliard 2005-03-23 13:18:51 +00:00
parent 93416cdaf7
commit 04881fae7a
6 changed files with 37 additions and 166 deletions

View File

@ -332,6 +332,8 @@ LRESULT HOOK_CallHooks( INT id, INT code, WPARAM wparam, LPARAM lparam, BOOL uni
BOOL unicode_hook = FALSE;
LRESULT ret = 0;
USER_CheckNotLock();
if (!queue) return 0;
SERVER_START_REQ( start_hook_chain )
{
@ -378,12 +380,10 @@ LRESULT HOOK_CallHooks( INT id, INT code, WPARAM wparam, LPARAM lparam, BOOL uni
if (!module[0] || (proc = get_hook_proc( proc, module )) != NULL)
{
int locks = WIN_SuspendWndsLock();
HHOOK prev = queue->hook;
queue->hook = handle;
ret = call_hook( proc, id, code, wparam, lparam, unicode, unicode_hook );
queue->hook = prev;
WIN_RestoreWndsLock( locks );
}
}
@ -772,6 +772,8 @@ void WINAPI NotifyWinEvent(DWORD event, HWND hwnd, LONG object_id, LONG child_id
return;
}
USER_CheckNotLock();
#if 0
if (event & 0x80000000)
{
@ -803,8 +805,6 @@ void WINAPI NotifyWinEvent(DWORD event, HWND hwnd, LONG object_id, LONG child_id
if (!info.module[0] || (info.proc = get_hook_proc( info.proc, info.module )) != NULL)
{
int locks = WIN_SuspendWndsLock();
if (TRACE_ON(relay))
DPRINTF( "%04lx:Call winevent hook proc %p (hhook=%p,event=%lx,hwnd=%p,object_id=%lx,child_id=%lx,tid=%04lx,time=%lx)\n",
GetCurrentThreadId(), info.proc, info.handle, event, hwnd, object_id,
@ -817,8 +817,6 @@ void WINAPI NotifyWinEvent(DWORD event, HWND hwnd, LONG object_id, LONG child_id
DPRINTF( "%04lx:Ret winevent hook proc %p (hhook=%p,event=%lx,hwnd=%p,object_id=%lx,child_id=%lx,tid=%04lx,time=%lx)\n",
GetCurrentThreadId(), info.proc, info.handle, event, hwnd, object_id,
child_id, GetCurrentThreadId(), GetCurrentTime());
WIN_RestoreWndsLock( locks );
}
}
else

View File

@ -2231,25 +2231,20 @@ static LRESULT retrieve_reply( const struct send_message_info *info,
static LRESULT send_inter_thread_message( DWORD dest_tid, const struct send_message_info *info,
LRESULT *res_ptr )
{
LRESULT ret;
int locks;
size_t reply_size = 0;
TRACE( "hwnd %p msg %x (%s) wp %x lp %lx\n",
info->hwnd, info->msg, SPY_GetMsgName(info->msg, info->hwnd), info->wparam, info->lparam );
USER_CheckNotLock();
if (!put_message_in_queue( dest_tid, info, &reply_size )) return 0;
/* there's no reply to wait for on notify/callback messages */
if (info->type == MSG_NOTIFY || info->type == MSG_CALLBACK) return 1;
locks = WIN_SuspendWndsLock();
wait_message_reply( info->flags );
ret = retrieve_reply( info, reply_size, res_ptr );
WIN_RestoreWndsLock( locks );
return ret;
return retrieve_reply( info, reply_size, res_ptr );
}
@ -2664,14 +2659,14 @@ BOOL WINAPI PeekMessageW( MSG *msg_out, HWND hwnd, UINT first, UINT last, UINT f
{
MESSAGEQUEUE *queue;
MSG msg;
int locks;
USER_CheckNotLock();
/* check for graphics events */
if (USER_Driver.pMsgWaitForMultipleObjectsEx)
USER_Driver.pMsgWaitForMultipleObjectsEx( 0, NULL, 0, QS_ALLINPUT, 0 );
hwnd = WIN_GetFullHandle( hwnd );
locks = WIN_SuspendWndsLock();
if (!peek_message( &msg, hwnd, first, last, (flags & PM_REMOVE) ? GET_MSG_REMOVE : 0 ))
{
@ -2681,7 +2676,6 @@ BOOL WINAPI PeekMessageW( MSG *msg_out, HWND hwnd, UINT first, UINT last, UINT f
ReleaseThunkLock(&count);
if (count) RestoreThunkLock(count);
}
WIN_RestoreWndsLock( locks );
return FALSE;
}
@ -2694,8 +2688,6 @@ BOOL WINAPI PeekMessageW( MSG *msg_out, HWND hwnd, UINT first, UINT last, UINT f
HOOK_CallHooks( WH_GETMESSAGE, HC_ACTION, flags & PM_REMOVE, (LPARAM)&msg, TRUE );
WIN_RestoreWndsLock( locks );
/* copy back our internal safe copy of message data to msg_out.
* msg_out is a variable from the *program*, so it can't be used
* internally as it can get "corrupted" by our use of SendMessage()
@ -2727,9 +2719,8 @@ BOOL WINAPI PeekMessageA( MSG *msg, HWND hwnd, UINT first, UINT last, UINT flags
BOOL WINAPI GetMessageW( MSG *msg, HWND hwnd, UINT first, UINT last )
{
MESSAGEQUEUE *queue = QUEUE_Current();
int mask, locks;
int mask = QS_POSTMESSAGE | QS_SENDMESSAGE; /* Always selected */
mask = QS_POSTMESSAGE | QS_SENDMESSAGE; /* Always selected */
if (first || last)
{
if ((first <= WM_KEYLAST) && (last >= WM_KEYFIRST)) mask |= QS_KEY;
@ -2741,8 +2732,6 @@ BOOL WINAPI GetMessageW( MSG *msg, HWND hwnd, UINT first, UINT last )
}
else mask |= QS_MOUSE | QS_KEY | QS_TIMER | QS_PAINT;
locks = WIN_SuspendWndsLock();
while (!PeekMessageW( msg, hwnd, first, last, PM_REMOVE ))
{
/* wait until one of the bits is set */
@ -2777,8 +2766,6 @@ BOOL WINAPI GetMessageW( MSG *msg, HWND hwnd, UINT first, UINT last )
if (dwlc) RestoreThunkLock( dwlc );
}
WIN_RestoreWndsLock( locks );
return (msg->message != WM_QUIT);
}

View File

@ -32,7 +32,6 @@
struct tagCLASS;
struct tagDCE;
struct tagMESSAGEQUEUE;
typedef struct tagWND
{
@ -60,7 +59,6 @@ typedef struct tagWND
HICON hIcon; /* window's icon */
HICON hIconSmall; /* window's small icon */
int cbWndExtra; /* class cbWndExtra at window creation */
int irefCount; /* window's reference count*/
DWORD userdata; /* User private data */
DWORD wExtra[1]; /* Window extra bytes */
} WND;
@ -76,10 +74,6 @@ typedef struct tagWND
/* Window functions */
extern WND *WIN_GetPtr( HWND hwnd );
extern int WIN_SuspendWndsLock( void );
extern void WIN_RestoreWndsLock(int ipreviousLock);
extern WND* WIN_FindWndPtr( HWND hwnd );
extern void WIN_ReleaseWndPtr(WND *wndPtr);
extern HWND WIN_Handle32( HWND16 hwnd16 );
extern HWND WIN_IsCurrentProcess( HWND hwnd );
extern HWND WIN_IsCurrentThread( HWND hwnd );
@ -105,7 +99,7 @@ inline static HWND WIN_GetFullHandle( HWND hwnd )
return hwnd;
}
/* to release pointers retrieved by WIN_GetPtr; do not confuse with WIN_ReleaseWndPtr!! */
/* to release pointers retrieved by WIN_GetPtr */
inline static void WIN_ReleasePtr( WND *ptr )
{
USER_Unlock();

View File

@ -150,36 +150,6 @@ void USER_CheckNotLock(void)
}
/***********************************************************************
* WIN_SuspendWndsLock
*
* Suspend the lock on WND structures.
* Returns the number of locks suspended
* FIXME: should be removed
*/
int WIN_SuspendWndsLock( void )
{
int isuspendedLocks = _ConfirmSysLevel( &USER_SysLevel );
int count = isuspendedLocks;
while ( count-- > 0 )
_LeaveSysLevel( &USER_SysLevel );
return isuspendedLocks;
}
/***********************************************************************
* WIN_RestoreWndsLock
*
* Restore the suspended locks on WND structures
* FIXME: should be removed
*/
void WIN_RestoreWndsLock( int ipreviousLocks )
{
while ( ipreviousLocks-- > 0 )
_EnterSysLevel( &USER_SysLevel );
}
/***********************************************************************
* SignalProc32 (USER.391)
* UserSignalProc (USER32.@)

View File

@ -116,7 +116,6 @@ static WND *create_window_handle( HWND parent, HWND owner, ATOM atom,
user_handles[index] = win;
win->hwndSelf = handle;
win->dwMagic = WND_MAGIC;
win->irefCount = 1;
win->cbWndExtra = extra_bytes;
memset( win->wExtra, 0, extra_bytes );
CLASS_AddWindow( class, win, type );
@ -149,6 +148,7 @@ static WND *free_window_handle( HWND hwnd )
SERVER_END_REQ;
}
USER_Unlock();
ptr->dwMagic = 0;
HeapFree( GetProcessHeap(), 0, ptr );
return ptr;
}
@ -388,63 +388,6 @@ HWND WIN_Handle32( HWND16 hwnd16 )
}
/***********************************************************************
* WIN_FindWndPtr
*
* Return a pointer to the WND structure corresponding to a HWND.
*/
WND * WIN_FindWndPtr( HWND hwnd )
{
WND * ptr;
if (!hwnd) return NULL;
if ((ptr = WIN_GetPtr( hwnd )))
{
if (ptr != WND_OTHER_PROCESS)
{
/* increment destruction monitoring */
ptr->irefCount++;
return ptr;
}
if (IsWindow( hwnd )) /* check other processes */
{
ERR( "window %p belongs to other process\n", hwnd );
/* DbgBreakPoint(); */
}
}
SetLastError( ERROR_INVALID_WINDOW_HANDLE );
return NULL;
}
/***********************************************************************
* WIN_ReleaseWndPtr
*
* Release the pointer to the WND structure.
*/
void WIN_ReleaseWndPtr(WND *wndPtr)
{
if(!wndPtr) return;
/* Decrement destruction monitoring value */
wndPtr->irefCount--;
/* Check if it's time to release the memory */
if(wndPtr->irefCount == 0 && !wndPtr->dwMagic)
{
/* Release memory */
free_window_handle( wndPtr->hwndSelf );
}
else if(wndPtr->irefCount < 0)
{
/* This else if is useful to monitor the WIN_ReleaseWndPtr function */
ERR("forgot a Lock on %p somewhere\n",wndPtr);
}
/* unlock all WND structures for thread safeness */
USER_Unlock();
}
/***********************************************************************
* WIN_UnlinkWindow
*
@ -622,6 +565,7 @@ LRESULT WIN_DestroyWindow( HWND hwnd )
{
WND *wndPtr;
HWND *list;
HMENU menu = 0, sys_menu;
TRACE("%p\n", hwnd );
@ -643,13 +587,6 @@ LRESULT WIN_DestroyWindow( HWND hwnd )
HeapFree( GetProcessHeap(), 0, list );
}
/*
* Clear the update region to make sure no WM_PAINT messages will be
* generated for this window while processing the WM_NCDESTROY.
*/
RedrawWindow( hwnd, NULL, 0,
RDW_VALIDATE | RDW_NOFRAME | RDW_NOERASE | RDW_NOINTERNALPAINT | RDW_NOCHILDREN);
/* Unlink now so we won't bother with the children later on */
WIN_UnlinkWindow( hwnd );
@ -664,23 +601,18 @@ LRESULT WIN_DestroyWindow( HWND hwnd )
/* free resources associated with the window */
if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
if (!(wndPtr = WIN_GetPtr( hwnd )) || wndPtr == WND_OTHER_PROCESS) return 0;
if (!(wndPtr->dwStyle & WS_CHILD)) menu = (HMENU)wndPtr->wIDmenu;
sys_menu = wndPtr->hSysMenu;
WIN_ReleasePtr( wndPtr );
if (menu) DestroyMenu( menu );
if (sys_menu) DestroyMenu( sys_menu );
if (!(wndPtr->dwStyle & WS_CHILD))
{
HMENU menu = (HMENU)SetWindowLongPtrW( hwnd, GWLP_ID, 0 );
if (menu) DestroyMenu( menu );
}
if (wndPtr->hSysMenu)
{
DestroyMenu( wndPtr->hSysMenu );
wndPtr->hSysMenu = 0;
}
DCE_FreeWindowDCE( hwnd ); /* Always do this to catch orphaned DCs */
if (USER_Driver.pDestroyWindow) USER_Driver.pDestroyWindow( hwnd );
wndPtr->class = NULL;
wndPtr->dwMagic = 0; /* Mark it as invalid */
WIN_ReleaseWndPtr( wndPtr );
free_window_handle( hwnd );
return 0;
}
@ -760,14 +692,11 @@ BOOL WIN_CreateDesktopWindow(void)
pWndDesktop->wIDmenu = reply->old_id;
}
SERVER_END_REQ;
WIN_ReleasePtr( pWndDesktop );
if (!USER_Driver.pCreateWindow || !USER_Driver.pCreateWindow( hwndDesktop, &cs, FALSE ))
{
WIN_ReleaseWndPtr( pWndDesktop );
return FALSE;
}
WIN_ReleaseWndPtr( pWndDesktop );
return TRUE;
}
@ -1210,7 +1139,7 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
}
}
else SetWindowLongPtrW( hwnd, GWLP_ID, (ULONG_PTR)cs->hMenu );
WIN_ReleaseWndPtr( wndPtr );
WIN_ReleasePtr( wndPtr );
if (!USER_Driver.pCreateWindow || !USER_Driver.pCreateWindow( hwnd, cs, unicode))
{
@ -2908,7 +2837,9 @@ BOOL WINAPI EnumWindows( WNDENUMPROC lpEnumFunc, LPARAM lParam )
{
HWND *list;
BOOL ret = TRUE;
int i, iWndsLocks;
int i;
USER_CheckNotLock();
/* We have to build a list of all windows first, to avoid */
/* unpleasant side-effects, for instance if the callback */
@ -2918,14 +2849,12 @@ BOOL WINAPI EnumWindows( WNDENUMPROC lpEnumFunc, LPARAM lParam )
/* Now call the callback function for every window */
iWndsLocks = WIN_SuspendWndsLock();
for (i = 0; list[i]; i++)
{
/* Make sure that the window still exists */
if (!IsWindow( list[i] )) continue;
if (!(ret = lpEnumFunc( list[i], lParam ))) break;
}
WIN_RestoreWndsLock(iWndsLocks);
HeapFree( GetProcessHeap(), 0, list );
return ret;
}
@ -2937,16 +2866,16 @@ BOOL WINAPI EnumWindows( WNDENUMPROC lpEnumFunc, LPARAM lParam )
BOOL WINAPI EnumThreadWindows( DWORD id, WNDENUMPROC func, LPARAM lParam )
{
HWND *list;
int i, iWndsLocks;
int i;
USER_CheckNotLock();
if (!(list = list_window_children( GetDesktopWindow(), 0, id ))) return TRUE;
/* Now call the callback function for every window */
iWndsLocks = WIN_SuspendWndsLock();
for (i = 0; list[i]; i++)
if (!func( list[i], lParam )) break;
WIN_RestoreWndsLock(iWndsLocks);
HeapFree( GetProcessHeap(), 0, list );
return TRUE;
}
@ -2990,12 +2919,11 @@ static BOOL WIN_EnumChildWindows( HWND *list, WNDENUMPROC func, LPARAM lParam )
BOOL WINAPI EnumChildWindows( HWND parent, WNDENUMPROC func, LPARAM lParam )
{
HWND *list;
int iWndsLocks;
USER_CheckNotLock();
if (!(list = WIN_ListChildren( parent ))) return FALSE;
iWndsLocks = WIN_SuspendWndsLock();
WIN_EnumChildWindows( list, func, lParam );
WIN_RestoreWndsLock(iWndsLocks);
HeapFree( GetProcessHeap(), 0, list );
return TRUE;
}

View File

@ -407,17 +407,15 @@ static LRESULT WINPROC_CallWndProc( WNDPROC proc, HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam )
{
LRESULT retvalue;
int iWndsLocks;
USER_CheckNotLock();
hwnd = WIN_GetFullHandle( hwnd );
if (TRACE_ON(relay))
DPRINTF( "%04lx:Call window proc %p (hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
GetCurrentThreadId(), proc, hwnd, SPY_GetMsgName(msg, hwnd), wParam, lParam );
/* To avoid any deadlocks, all the locks on the windows structures
must be suspended before the control is passed to the application */
iWndsLocks = WIN_SuspendWndsLock();
retvalue = WINPROC_wrapper( proc, hwnd, msg, wParam, lParam );
WIN_RestoreWndsLock(iWndsLocks);
if (TRACE_ON(relay))
DPRINTF( "%04lx:Ret window proc %p (hwnd=%p,msg=%s,wp=%08x,lp=%08lx) retval=%08lx\n",
@ -439,7 +437,8 @@ static LRESULT WINAPI WINPROC_CallWndProc16( WNDPROC16 proc, HWND16 hwnd,
WORD args[5];
DWORD offset = 0;
TEB *teb = NtCurrentTeb();
int iWndsLocks;
USER_CheckNotLock();
/* Window procedures want ax = hInstance, ds = es = ss */
@ -479,8 +478,6 @@ static LRESULT WINAPI WINPROC_CallWndProc16( WNDPROC16 proc, HWND16 hwnd,
}
}
iWndsLocks = WIN_SuspendWndsLock();
args[4] = hwnd;
args[3] = msg;
args[2] = wParam;
@ -490,9 +487,6 @@ static LRESULT WINAPI WINPROC_CallWndProc16( WNDPROC16 proc, HWND16 hwnd,
ret = MAKELONG( LOWORD(context.Eax), LOWORD(context.Edx) );
if (offset) stack16_pop( offset );
WIN_RestoreWndsLock(iWndsLocks);
return ret;
}