From 7695d69046b9bb4a2372575988fe4b3cb423091a Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Mon, 24 Sep 2001 01:19:59 +0000 Subject: [PATCH] A couple of optimizations to avoid some server calls in WIN_FindWndPtr and related functions. --- dlls/user/msg16.c | 3 +- include/win.h | 2 + include/wine/server_protocol.h | 6 ++- server/protocol.def | 6 ++- server/trace.c | 2 +- server/user.c | 10 ++-- windows/message.c | 2 +- windows/timer.c | 2 +- windows/win.c | 106 +++++++++++++++++++++++++++++------------ windows/winpos.c | 58 ++++++++-------------- 10 files changed, 116 insertions(+), 81 deletions(-) diff --git a/dlls/user/msg16.c b/dlls/user/msg16.c index c8271071529..2ed9979b70b 100644 --- a/dlls/user/msg16.c +++ b/dlls/user/msg16.c @@ -25,8 +25,7 @@ LRESULT WINAPI SendMessage16( HWND16 hwnd16, UINT16 msg, WPARAM16 wparam, LPARAM LRESULT result; HWND hwnd = WIN_Handle32( hwnd16 ); - if (hwnd != HWND_BROADCAST && - GetWindowThreadProcessId( hwnd, NULL ) == GetCurrentThreadId()) + if (hwnd != HWND_BROADCAST && WIN_IsCurrentThread(hwnd)) { /* call 16-bit window proc directly */ WNDPROC16 winproc; diff --git a/include/win.h b/include/win.h index 8cc7bdbad89..8d412095c70 100644 --- a/include/win.h +++ b/include/win.h @@ -86,6 +86,8 @@ extern WND* WIN_LockWndPtr(WND *wndPtr); extern void WIN_ReleaseWndPtr(WND *wndPtr); extern void WIN_UpdateWndPtr(WND **oldPtr,WND *newPtr); extern HWND WIN_Handle32( HWND16 hwnd16 ); +extern BOOL WIN_IsCurrentProcess( HWND hwnd ); +extern BOOL WIN_IsCurrentThread( HWND hwnd ); extern void WIN_LinkWindow( HWND hwnd, HWND parent, HWND hwndInsertAfter ); extern void WIN_UnlinkWindow( HWND hwnd ); extern HWND WIN_FindWinToRepaint( HWND hwnd ); diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 18ecc74b8e4..c94d2d40fe3 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -40,6 +40,10 @@ struct request_max_size typedef int handle_t; typedef unsigned int user_handle_t; +#define FIRST_USER_HANDLE 0x0020 +#define LAST_USER_HANDLE 0xffef + + struct debug_event_exception { @@ -1617,7 +1621,7 @@ struct get_window_children_request struct request_header __header; user_handle_t parent; int count; - /* VARARG(parents,user_handles); */ + /* VARARG(children,user_handles); */ }; diff --git a/server/protocol.def b/server/protocol.def index a87287c8a12..010d2edf827 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -42,6 +42,10 @@ struct request_max_size typedef int handle_t; typedef unsigned int user_handle_t; +#define FIRST_USER_HANDLE 0x0020 /* first possible value for low word of user handle */ +#define LAST_USER_HANDLE 0xffef /* last possible value for low word of user handle */ + + /* definitions of the event data depending on the event code */ struct debug_event_exception { @@ -1443,7 +1447,7 @@ enum message_type user_handle_t parent; /* parent window */ @REPLY int count; /* total count of children */ - VARARG(parents,user_handles); /* children handles */ + VARARG(children,user_handles); /* children handles */ @END diff --git a/server/trace.c b/server/trace.c index 93a4f367977..66d58f9f45c 100644 --- a/server/trace.c +++ b/server/trace.c @@ -1722,7 +1722,7 @@ static void dump_get_window_children_request( const struct get_window_children_r static void dump_get_window_children_reply( const struct get_window_children_request *req ) { fprintf( stderr, " count=%d,", req->count ); - fprintf( stderr, " parents=" ); + fprintf( stderr, " children=" ); cur_pos += dump_varargs_user_handles( req ); } diff --git a/server/user.c b/server/user.c index e31fb162320..e28189c7ab0 100644 --- a/server/user.c +++ b/server/user.c @@ -19,13 +19,9 @@ static struct user_handle *freelist; static int nb_handles; static int allocated_handles; -#define FIRST_HANDLE 32 /* handle value for first table entry */ -#define LAST_HANDLE (65536 - 16) -#define MAX_HANDLES (LAST_HANDLE - FIRST_HANDLE) - static struct user_handle *handle_to_entry( user_handle_t handle ) { - int index = (handle & 0xffff) - FIRST_HANDLE; + int index = (handle & 0xffff) - FIRST_USER_HANDLE; if (index < 0 || index >= nb_handles) return NULL; if (!handles[index].type) return NULL; if ((handle >> 16) && (handle >> 16 != handles[index].generation)) return NULL; @@ -35,7 +31,7 @@ static struct user_handle *handle_to_entry( user_handle_t handle ) inline static user_handle_t entry_to_handle( struct user_handle *ptr ) { int index = ptr - handles; - return (index + FIRST_HANDLE) + (ptr->generation << 16); + return (index + FIRST_USER_HANDLE) + (ptr->generation << 16); } inline static struct user_handle *alloc_user_entry(void) @@ -53,7 +49,7 @@ inline static struct user_handle *alloc_user_entry(void) struct user_handle *new_handles; /* grow array by 50% (but at minimum 32 entries) */ int growth = max( 32, allocated_handles / 2 ); - int new_size = min( allocated_handles + growth, MAX_HANDLES ); + int new_size = min( allocated_handles + growth, LAST_USER_HANDLE-FIRST_USER_HANDLE+1 ); if (new_size <= allocated_handles) return NULL; if (!(new_handles = realloc( handles, new_size * sizeof(*handles) ))) return NULL; diff --git a/windows/message.c b/windows/message.c index 1a68a2267bf..638e4740866 100644 --- a/windows/message.c +++ b/windows/message.c @@ -506,7 +506,7 @@ BOOL MSG_process_raw_hardware_message( MSG *msg, ULONG_PTR extra_info, HWND hwnd /* check destination thread and filters */ if (!check_message_filter( msg, hwnd_filter, first, last ) || - GetWindowThreadProcessId( msg->hwnd, NULL ) != GetCurrentThreadId()) + !WIN_IsCurrentThread( msg->hwnd )) { /* queue it for later, or for another thread */ queue_hardware_message( msg, extra_info, MSG_HARDWARE_COOKED ); diff --git a/windows/timer.c b/windows/timer.c index f0651a20cf6..0f760db7ae2 100644 --- a/windows/timer.c +++ b/windows/timer.c @@ -104,7 +104,7 @@ static UINT TIMER_SetTimer( HWND hwnd, UINT id, UINT timeout, TIMER * pTimer; HWINDOWPROC winproc = 0; - if (hwnd && GetWindowThreadProcessId( hwnd, NULL ) != GetCurrentThreadId()) + if (hwnd && !WIN_IsCurrentThread( hwnd )) { SetLastError( ERROR_INVALID_WINDOW_HANDLE ); return 0; diff --git a/windows/win.c b/windows/win.c index a587caebf99..a080870bb94 100644 --- a/windows/win.c +++ b/windows/win.c @@ -4,6 +4,7 @@ * Copyright 1993, 1994 Alexandre Julliard */ +#include #include #include #include "windef.h" @@ -29,6 +30,9 @@ DEFAULT_DEBUG_CHANNEL(win); DECLARE_DEBUG_CHANNEL(msg); +#define BAD_WND_PTR ((WND *)1) /* returned by get_wnd_ptr on bad window handles */ +#define NB_USER_HANDLES (LAST_USER_HANDLE - FIRST_USER_HANDLE + 1) + /**********************************************************************/ /* Desktop window */ @@ -37,7 +41,7 @@ static WND *pWndDesktop = NULL; static WORD wDragWidth = 4; static WORD wDragHeight= 3; -static void *user_handles[65536]; +static void *user_handles[NB_USER_HANDLES]; /* thread safeness */ extern SYSLEVEL USER_SysLevel; /* FIXME */ @@ -79,6 +83,7 @@ static WND *create_window_handle( HWND parent, HWND owner, INT size ) { BOOL res; user_handle_t handle = 0; + WORD index; WND *win = HeapAlloc( GetProcessHeap(), 0, size ); if (!win) return NULL; @@ -99,7 +104,9 @@ static WND *create_window_handle( HWND parent, HWND owner, INT size ) HeapFree( GetProcessHeap(), 0, win ); return NULL; } - user_handles[LOWORD(handle)] = win; + index = LOWORD(handle) - FIRST_USER_HANDLE; + assert( index < NB_USER_HANDLES ); + user_handles[index] = win; win->hwndSelf = handle; win->dwMagic = WND_MAGIC; win->irefCount = 1; @@ -115,15 +122,17 @@ static WND *create_window_handle( HWND parent, HWND owner, INT size ) static WND *free_window_handle( HWND hwnd ) { WND *ptr; + WORD index = LOWORD(hwnd) - FIRST_USER_HANDLE; + if (index >= NB_USER_HANDLES) return NULL; USER_Lock(); - if ((ptr = user_handles[LOWORD(hwnd)])) + if ((ptr = user_handles[index])) { SERVER_START_REQ( destroy_window ) { req->handle = hwnd; if (!SERVER_CALL_ERR()) - user_handles[LOWORD(hwnd)] = NULL; + user_handles[index] = NULL; else ptr = NULL; } @@ -138,23 +147,60 @@ static WND *free_window_handle( HWND hwnd ) /*********************************************************************** * get_wnd_ptr * - * Return a pointer to the WND structure if local to the process. - * If ret value is non-NULL, the user lock is held. + * Return a pointer to the WND structure if local to the process, + * or BAD_WND_PTR is handle is local but not valid. + * If ret value is a valid pointer, the user lock is held. */ static WND *get_wnd_ptr( HWND hwnd ) { WND * ptr; + WORD index = LOWORD(hwnd) - FIRST_USER_HANDLE; - if (!hwnd) return NULL; + if (index >= NB_USER_HANDLES) return BAD_WND_PTR; USER_Lock(); - if ((ptr = user_handles[LOWORD(hwnd)])) + if ((ptr = user_handles[index])) { if (ptr->dwMagic == WND_MAGIC && (!HIWORD(hwnd) || hwnd == ptr->hwndSelf)) return ptr; + ptr = BAD_WND_PTR; } USER_Unlock(); - return NULL; + return ptr; +} + + +/*********************************************************************** + * WIN_IsCurrentProcess + * + * Check whether a given window belongs to the current process. + */ +BOOL WIN_IsCurrentProcess( HWND hwnd ) +{ + WND *ptr; + + if (!(ptr = get_wnd_ptr( hwnd )) || ptr == BAD_WND_PTR) return FALSE; + USER_Unlock(); + return TRUE; +} + + +/*********************************************************************** + * WIN_IsCurrentThread + * + * Check whether a given window belongs to the current thread. + */ +BOOL WIN_IsCurrentThread( HWND hwnd ) +{ + WND *ptr; + BOOL ret = FALSE; + + if ((ptr = get_wnd_ptr( hwnd )) && ptr != BAD_WND_PTR) + { + ret = (ptr->tid == GetCurrentThreadId()); + USER_Unlock(); + } + return ret; } @@ -174,8 +220,11 @@ HWND WIN_Handle32( HWND16 hwnd16 ) if ((ptr = get_wnd_ptr( hwnd ))) { - hwnd = ptr->hwndSelf; - USER_Unlock(); + if (ptr != BAD_WND_PTR) + { + hwnd = ptr->hwndSelf; + USER_Unlock(); + } } else /* may belong to another process */ { @@ -203,13 +252,14 @@ WND * WIN_FindWndPtr( HWND hwnd ) if ((ptr = get_wnd_ptr( hwnd ))) { - /* increment destruction monitoring */ - ptr->irefCount++; - return ptr; + if (ptr != BAD_WND_PTR) + { + /* increment destruction monitoring */ + ptr->irefCount++; + return ptr; + } } - - /* check other processes */ - if (IsWindow( hwnd )) + else if (IsWindow( hwnd )) /* check other processes */ { ERR( "window %04x belongs to other process\n", hwnd ); /* DbgBreakPoint(); */ @@ -379,7 +429,7 @@ HWND WIN_FindWinToRepaint( HWND hwnd ) { if (!(pWnd->dwStyle & WS_VISIBLE)) continue; if ((pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT)) && - GetWindowThreadProcessId( pWnd->hwndSelf, NULL ) == GetCurrentThreadId()) + WIN_IsCurrentThread( pWnd->hwndSelf )) break; if (pWnd->child ) { @@ -403,7 +453,7 @@ HWND WIN_FindWinToRepaint( HWND hwnd ) { if (!(pWnd->dwExStyle & WS_EX_TRANSPARENT) && (pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT)) && - GetWindowThreadProcessId( pWnd->hwndSelf, NULL ) == GetCurrentThreadId()) + WIN_IsCurrentThread( pWnd->hwndSelf )) { hwndRet = pWnd->hwndSelf; WIN_ReleaseWndPtr(pWnd); @@ -502,7 +552,7 @@ void WIN_DestroyThreadWindows( HWND hwnd ) for (i = 0; list[i]; i++) { if (!IsWindow( list[i] )) continue; - if (GetWindowThreadProcessId( list[i], NULL ) == GetCurrentThreadId()) + if (WIN_IsCurrentThread( list[i] )) DestroyWindow( list[i] ); else WIN_DestroyThreadWindows( list[i] ); @@ -1951,14 +2001,12 @@ BOOL WINAPI IsWindow( HWND hwnd ) WND *ptr; BOOL ret; - USER_Lock(); - if ((ptr = user_handles[LOWORD(hwnd)])) + if ((ptr = get_wnd_ptr( hwnd ))) { - ret = ((ptr->dwMagic == WND_MAGIC) && (!HIWORD(hwnd) || hwnd == ptr->hwndSelf)); + if (ptr == BAD_WND_PTR) return FALSE; USER_Unlock(); - return ret; + return TRUE; } - USER_Unlock(); /* check other processes */ SERVER_START_REQ( get_window_info ) @@ -1979,20 +2027,18 @@ DWORD WINAPI GetWindowThreadProcessId( HWND hwnd, LPDWORD process ) WND *ptr; DWORD tid = 0; - USER_Lock(); - if ((ptr = user_handles[LOWORD(hwnd)])) + if ((ptr = get_wnd_ptr( hwnd ))) { - if ((ptr->dwMagic == WND_MAGIC) && (!HIWORD(hwnd) || hwnd == ptr->hwndSelf)) + if (ptr != BAD_WND_PTR) { /* got a valid window */ tid = ptr->tid; if (process) *process = GetCurrentProcessId(); + USER_Unlock(); } else SetLastError( ERROR_INVALID_WINDOW_HANDLE); - USER_Unlock(); return tid; } - USER_Unlock(); /* check other processes */ SERVER_START_REQ( get_window_info ) diff --git a/windows/winpos.c b/windows/winpos.c index 1779348a262..285f5b5308a 100644 --- a/windows/winpos.c +++ b/windows/winpos.c @@ -375,8 +375,8 @@ hittest: if (!hwnd_ret) hwnd_ret = hwndScope; /* Send the WM_NCHITTEST message (only if to the same task) */ - if (GetWindowThreadProcessId( hwnd_ret, NULL ) == GetCurrentThreadId()) - { + if (WIN_IsCurrentThread( hwnd_ret )) + { INT res = SendMessageA( hwnd_ret, WM_NCHITTEST, 0, MAKELONG( pt.x, pt.y ) ); if (res != HTTRANSPARENT) { @@ -620,47 +620,44 @@ HWND WINAPI SetActiveWindow( HWND hwnd ) WND *wndPtr = WIN_FindWndPtr( hwnd ); MESSAGEQUEUE *pMsgQ = 0, *pCurMsgQ = 0; - if (!wndPtr || (wndPtr->dwStyle & (WS_DISABLED | WS_CHILD))) - { - prev = 0; - goto end; - } + if (!wndPtr) return 0; + + if (wndPtr->dwStyle & (WS_DISABLED | WS_CHILD)) goto error; /* Get the messageQ for the current thread */ if (!(pCurMsgQ = QUEUE_Current())) { WARN("\tCurrent message queue not found. Exiting!\n" ); - goto CLEANUP; + goto error; } - + /* Retrieve the message queue associated with this window */ pMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( wndPtr->hmemTaskQ ); if ( !pMsgQ ) { WARN("\tWindow message queue not found. Exiting!\n" ); - goto CLEANUP; + goto error; } /* Make sure that the window is associated with the calling threads * message queue. It must share the same perQ data. */ - if ( pCurMsgQ->pQData != pMsgQ->pQData ) - goto CLEANUP; - + { + QUEUE_Unlock( pMsgQ ); + goto error; + } + /* Save current active window */ prev = PERQDATA_GetActiveWnd( pMsgQ->pQData ); - + QUEUE_Unlock( pMsgQ ); + WIN_ReleaseWndPtr(wndPtr); WINPOS_SetActiveWindow( hwnd, 0, 0 ); + return prev; -CLEANUP: - /* Unlock the queues before returning */ - if ( pMsgQ ) - QUEUE_Unlock( pMsgQ ); - -end: + error: WIN_ReleaseWndPtr(wndPtr); - return prev; + return 0; } @@ -1399,7 +1396,6 @@ BOOL WINPOS_ActivateOtherWindow(HWND hwnd) BOOL WINPOS_ChangeActiveWindow( HWND hWnd, BOOL mouseMsg ) { WND *wndPtr; - BOOL retvalue; HWND hwndActive = 0; /* Get current active window from the active queue */ @@ -1425,23 +1421,11 @@ BOOL WINPOS_ChangeActiveWindow( HWND hWnd, BOOL mouseMsg ) WIN_ReleaseWndPtr(wndPtr); return SendMessageA(hWnd, WM_CHILDACTIVATE, 0, 0L); } + WIN_ReleaseWndPtr(wndPtr); - if( hWnd == hwndActive ) - { - retvalue = FALSE; - goto end; - } - - if( !WINPOS_SetActiveWindow(hWnd ,mouseMsg ,TRUE) ) - { - retvalue = FALSE; - goto end; - } + if( hWnd == hwndActive ) return FALSE; - retvalue = TRUE; -end: - WIN_ReleaseWndPtr(wndPtr); - return retvalue; + return WINPOS_SetActiveWindow(hWnd ,mouseMsg ,TRUE); } -- 2.11.4.GIT