A couple of optimizations to avoid some server calls in WIN_FindWndPtr

and related functions.
This commit is contained in:
Alexandre Julliard 2001-09-24 01:19:59 +00:00
parent 5af055d8df
commit 7695d69046
10 changed files with 118 additions and 83 deletions

View File

@ -25,8 +25,7 @@ LRESULT WINAPI SendMessage16( HWND16 hwnd16, UINT16 msg, WPARAM16 wparam, LPARAM
LRESULT result; LRESULT result;
HWND hwnd = WIN_Handle32( hwnd16 ); HWND hwnd = WIN_Handle32( hwnd16 );
if (hwnd != HWND_BROADCAST && if (hwnd != HWND_BROADCAST && WIN_IsCurrentThread(hwnd))
GetWindowThreadProcessId( hwnd, NULL ) == GetCurrentThreadId())
{ {
/* call 16-bit window proc directly */ /* call 16-bit window proc directly */
WNDPROC16 winproc; WNDPROC16 winproc;

View File

@ -86,6 +86,8 @@ extern WND* WIN_LockWndPtr(WND *wndPtr);
extern void WIN_ReleaseWndPtr(WND *wndPtr); extern void WIN_ReleaseWndPtr(WND *wndPtr);
extern void WIN_UpdateWndPtr(WND **oldPtr,WND *newPtr); extern void WIN_UpdateWndPtr(WND **oldPtr,WND *newPtr);
extern HWND WIN_Handle32( HWND16 hwnd16 ); 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_LinkWindow( HWND hwnd, HWND parent, HWND hwndInsertAfter );
extern void WIN_UnlinkWindow( HWND hwnd ); extern void WIN_UnlinkWindow( HWND hwnd );
extern HWND WIN_FindWinToRepaint( HWND hwnd ); extern HWND WIN_FindWinToRepaint( HWND hwnd );

View File

@ -40,6 +40,10 @@ struct request_max_size
typedef int handle_t; typedef int handle_t;
typedef unsigned int user_handle_t; typedef unsigned int user_handle_t;
#define FIRST_USER_HANDLE 0x0020
#define LAST_USER_HANDLE 0xffef
struct debug_event_exception struct debug_event_exception
{ {
@ -1617,7 +1621,7 @@ struct get_window_children_request
struct request_header __header; struct request_header __header;
user_handle_t parent; user_handle_t parent;
int count; int count;
/* VARARG(parents,user_handles); */ /* VARARG(children,user_handles); */
}; };

View File

@ -42,6 +42,10 @@ struct request_max_size
typedef int handle_t; typedef int handle_t;
typedef unsigned int user_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 */ /* definitions of the event data depending on the event code */
struct debug_event_exception struct debug_event_exception
{ {
@ -1443,7 +1447,7 @@ enum message_type
user_handle_t parent; /* parent window */ user_handle_t parent; /* parent window */
@REPLY @REPLY
int count; /* total count of children */ int count; /* total count of children */
VARARG(parents,user_handles); /* children handles */ VARARG(children,user_handles); /* children handles */
@END @END

View File

@ -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 ) static void dump_get_window_children_reply( const struct get_window_children_request *req )
{ {
fprintf( stderr, " count=%d,", req->count ); fprintf( stderr, " count=%d,", req->count );
fprintf( stderr, " parents=" ); fprintf( stderr, " children=" );
cur_pos += dump_varargs_user_handles( req ); cur_pos += dump_varargs_user_handles( req );
} }

View File

@ -19,13 +19,9 @@ static struct user_handle *freelist;
static int nb_handles; static int nb_handles;
static int allocated_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 ) 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 (index < 0 || index >= nb_handles) return NULL;
if (!handles[index].type) return NULL; if (!handles[index].type) return NULL;
if ((handle >> 16) && (handle >> 16 != handles[index].generation)) 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 ) inline static user_handle_t entry_to_handle( struct user_handle *ptr )
{ {
int index = ptr - handles; 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) 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; struct user_handle *new_handles;
/* grow array by 50% (but at minimum 32 entries) */ /* grow array by 50% (but at minimum 32 entries) */
int growth = max( 32, allocated_handles / 2 ); 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_size <= allocated_handles) return NULL;
if (!(new_handles = realloc( handles, new_size * sizeof(*handles) ))) if (!(new_handles = realloc( handles, new_size * sizeof(*handles) )))
return NULL; return NULL;

View File

@ -506,7 +506,7 @@ BOOL MSG_process_raw_hardware_message( MSG *msg, ULONG_PTR extra_info, HWND hwnd
/* check destination thread and filters */ /* check destination thread and filters */
if (!check_message_filter( msg, hwnd_filter, first, last ) || 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 it for later, or for another thread */
queue_hardware_message( msg, extra_info, MSG_HARDWARE_COOKED ); queue_hardware_message( msg, extra_info, MSG_HARDWARE_COOKED );

View File

@ -104,7 +104,7 @@ static UINT TIMER_SetTimer( HWND hwnd, UINT id, UINT timeout,
TIMER * pTimer; TIMER * pTimer;
HWINDOWPROC winproc = 0; HWINDOWPROC winproc = 0;
if (hwnd && GetWindowThreadProcessId( hwnd, NULL ) != GetCurrentThreadId()) if (hwnd && !WIN_IsCurrentThread( hwnd ))
{ {
SetLastError( ERROR_INVALID_WINDOW_HANDLE ); SetLastError( ERROR_INVALID_WINDOW_HANDLE );
return 0; return 0;

View File

@ -4,6 +4,7 @@
* Copyright 1993, 1994 Alexandre Julliard * Copyright 1993, 1994 Alexandre Julliard
*/ */
#include <assert.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "windef.h" #include "windef.h"
@ -29,6 +30,9 @@
DEFAULT_DEBUG_CHANNEL(win); DEFAULT_DEBUG_CHANNEL(win);
DECLARE_DEBUG_CHANNEL(msg); 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 */ /* Desktop window */
@ -37,7 +41,7 @@ static WND *pWndDesktop = NULL;
static WORD wDragWidth = 4; static WORD wDragWidth = 4;
static WORD wDragHeight= 3; static WORD wDragHeight= 3;
static void *user_handles[65536]; static void *user_handles[NB_USER_HANDLES];
/* thread safeness */ /* thread safeness */
extern SYSLEVEL USER_SysLevel; /* FIXME */ extern SYSLEVEL USER_SysLevel; /* FIXME */
@ -79,6 +83,7 @@ static WND *create_window_handle( HWND parent, HWND owner, INT size )
{ {
BOOL res; BOOL res;
user_handle_t handle = 0; user_handle_t handle = 0;
WORD index;
WND *win = HeapAlloc( GetProcessHeap(), 0, size ); WND *win = HeapAlloc( GetProcessHeap(), 0, size );
if (!win) return NULL; if (!win) return NULL;
@ -99,7 +104,9 @@ static WND *create_window_handle( HWND parent, HWND owner, INT size )
HeapFree( GetProcessHeap(), 0, win ); HeapFree( GetProcessHeap(), 0, win );
return NULL; 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->hwndSelf = handle;
win->dwMagic = WND_MAGIC; win->dwMagic = WND_MAGIC;
win->irefCount = 1; 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 ) static WND *free_window_handle( HWND hwnd )
{ {
WND *ptr; WND *ptr;
WORD index = LOWORD(hwnd) - FIRST_USER_HANDLE;
if (index >= NB_USER_HANDLES) return NULL;
USER_Lock(); USER_Lock();
if ((ptr = user_handles[LOWORD(hwnd)])) if ((ptr = user_handles[index]))
{ {
SERVER_START_REQ( destroy_window ) SERVER_START_REQ( destroy_window )
{ {
req->handle = hwnd; req->handle = hwnd;
if (!SERVER_CALL_ERR()) if (!SERVER_CALL_ERR())
user_handles[LOWORD(hwnd)] = NULL; user_handles[index] = NULL;
else else
ptr = NULL; ptr = NULL;
} }
@ -138,23 +147,60 @@ static WND *free_window_handle( HWND hwnd )
/*********************************************************************** /***********************************************************************
* get_wnd_ptr * get_wnd_ptr
* *
* Return a pointer to the WND structure if local to the process. * Return a pointer to the WND structure if local to the process,
* If ret value is non-NULL, the user lock is held. * 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 ) static WND *get_wnd_ptr( HWND hwnd )
{ {
WND * ptr; WND * ptr;
WORD index = LOWORD(hwnd) - FIRST_USER_HANDLE;
if (!hwnd) return NULL; if (index >= NB_USER_HANDLES) return BAD_WND_PTR;
USER_Lock(); USER_Lock();
if ((ptr = user_handles[LOWORD(hwnd)])) if ((ptr = user_handles[index]))
{ {
if (ptr->dwMagic == WND_MAGIC && (!HIWORD(hwnd) || hwnd == ptr->hwndSelf)) if (ptr->dwMagic == WND_MAGIC && (!HIWORD(hwnd) || hwnd == ptr->hwndSelf))
return ptr; return ptr;
ptr = BAD_WND_PTR;
} }
USER_Unlock(); 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 ))) if ((ptr = get_wnd_ptr( hwnd )))
{ {
hwnd = ptr->hwndSelf; if (ptr != BAD_WND_PTR)
USER_Unlock(); {
hwnd = ptr->hwndSelf;
USER_Unlock();
}
} }
else /* may belong to another process */ else /* may belong to another process */
{ {
@ -203,13 +252,14 @@ WND * WIN_FindWndPtr( HWND hwnd )
if ((ptr = get_wnd_ptr( hwnd ))) if ((ptr = get_wnd_ptr( hwnd )))
{ {
/* increment destruction monitoring */ if (ptr != BAD_WND_PTR)
ptr->irefCount++; {
return ptr; /* increment destruction monitoring */
ptr->irefCount++;
return ptr;
}
} }
else if (IsWindow( hwnd )) /* check other processes */
/* check other processes */
if (IsWindow( hwnd ))
{ {
ERR( "window %04x belongs to other process\n", hwnd ); ERR( "window %04x belongs to other process\n", hwnd );
/* DbgBreakPoint(); */ /* DbgBreakPoint(); */
@ -379,7 +429,7 @@ HWND WIN_FindWinToRepaint( HWND hwnd )
{ {
if (!(pWnd->dwStyle & WS_VISIBLE)) continue; if (!(pWnd->dwStyle & WS_VISIBLE)) continue;
if ((pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT)) && if ((pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT)) &&
GetWindowThreadProcessId( pWnd->hwndSelf, NULL ) == GetCurrentThreadId()) WIN_IsCurrentThread( pWnd->hwndSelf ))
break; break;
if (pWnd->child ) if (pWnd->child )
{ {
@ -403,7 +453,7 @@ HWND WIN_FindWinToRepaint( HWND hwnd )
{ {
if (!(pWnd->dwExStyle & WS_EX_TRANSPARENT) && if (!(pWnd->dwExStyle & WS_EX_TRANSPARENT) &&
(pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT)) && (pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT)) &&
GetWindowThreadProcessId( pWnd->hwndSelf, NULL ) == GetCurrentThreadId()) WIN_IsCurrentThread( pWnd->hwndSelf ))
{ {
hwndRet = pWnd->hwndSelf; hwndRet = pWnd->hwndSelf;
WIN_ReleaseWndPtr(pWnd); WIN_ReleaseWndPtr(pWnd);
@ -502,7 +552,7 @@ void WIN_DestroyThreadWindows( HWND hwnd )
for (i = 0; list[i]; i++) for (i = 0; list[i]; i++)
{ {
if (!IsWindow( list[i] )) continue; if (!IsWindow( list[i] )) continue;
if (GetWindowThreadProcessId( list[i], NULL ) == GetCurrentThreadId()) if (WIN_IsCurrentThread( list[i] ))
DestroyWindow( list[i] ); DestroyWindow( list[i] );
else else
WIN_DestroyThreadWindows( list[i] ); WIN_DestroyThreadWindows( list[i] );
@ -1951,14 +2001,12 @@ BOOL WINAPI IsWindow( HWND hwnd )
WND *ptr; WND *ptr;
BOOL ret; BOOL ret;
USER_Lock(); if ((ptr = get_wnd_ptr( hwnd )))
if ((ptr = user_handles[LOWORD(hwnd)]))
{ {
ret = ((ptr->dwMagic == WND_MAGIC) && (!HIWORD(hwnd) || hwnd == ptr->hwndSelf)); if (ptr == BAD_WND_PTR) return FALSE;
USER_Unlock(); USER_Unlock();
return ret; return TRUE;
} }
USER_Unlock();
/* check other processes */ /* check other processes */
SERVER_START_REQ( get_window_info ) SERVER_START_REQ( get_window_info )
@ -1979,20 +2027,18 @@ DWORD WINAPI GetWindowThreadProcessId( HWND hwnd, LPDWORD process )
WND *ptr; WND *ptr;
DWORD tid = 0; DWORD tid = 0;
USER_Lock(); if ((ptr = get_wnd_ptr( hwnd )))
if ((ptr = user_handles[LOWORD(hwnd)]))
{ {
if ((ptr->dwMagic == WND_MAGIC) && (!HIWORD(hwnd) || hwnd == ptr->hwndSelf)) if (ptr != BAD_WND_PTR)
{ {
/* got a valid window */ /* got a valid window */
tid = ptr->tid; tid = ptr->tid;
if (process) *process = GetCurrentProcessId(); if (process) *process = GetCurrentProcessId();
USER_Unlock();
} }
else SetLastError( ERROR_INVALID_WINDOW_HANDLE); else SetLastError( ERROR_INVALID_WINDOW_HANDLE);
USER_Unlock();
return tid; return tid;
} }
USER_Unlock();
/* check other processes */ /* check other processes */
SERVER_START_REQ( get_window_info ) SERVER_START_REQ( get_window_info )

View File

@ -375,8 +375,8 @@ hittest:
if (!hwnd_ret) hwnd_ret = hwndScope; if (!hwnd_ret) hwnd_ret = hwndScope;
/* Send the WM_NCHITTEST message (only if to the same task) */ /* 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 ) ); INT res = SendMessageA( hwnd_ret, WM_NCHITTEST, 0, MAKELONG( pt.x, pt.y ) );
if (res != HTTRANSPARENT) if (res != HTTRANSPARENT)
{ {
@ -620,47 +620,44 @@ HWND WINAPI SetActiveWindow( HWND hwnd )
WND *wndPtr = WIN_FindWndPtr( hwnd ); WND *wndPtr = WIN_FindWndPtr( hwnd );
MESSAGEQUEUE *pMsgQ = 0, *pCurMsgQ = 0; MESSAGEQUEUE *pMsgQ = 0, *pCurMsgQ = 0;
if (!wndPtr || (wndPtr->dwStyle & (WS_DISABLED | WS_CHILD))) if (!wndPtr) return 0;
{
prev = 0; if (wndPtr->dwStyle & (WS_DISABLED | WS_CHILD)) goto error;
goto end;
}
/* Get the messageQ for the current thread */ /* Get the messageQ for the current thread */
if (!(pCurMsgQ = QUEUE_Current())) if (!(pCurMsgQ = QUEUE_Current()))
{ {
WARN("\tCurrent message queue not found. Exiting!\n" ); WARN("\tCurrent message queue not found. Exiting!\n" );
goto CLEANUP; goto error;
} }
/* Retrieve the message queue associated with this window */ /* Retrieve the message queue associated with this window */
pMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( wndPtr->hmemTaskQ ); pMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( wndPtr->hmemTaskQ );
if ( !pMsgQ ) if ( !pMsgQ )
{ {
WARN("\tWindow message queue not found. Exiting!\n" ); WARN("\tWindow message queue not found. Exiting!\n" );
goto CLEANUP; goto error;
} }
/* Make sure that the window is associated with the calling threads /* Make sure that the window is associated with the calling threads
* message queue. It must share the same perQ data. * message queue. It must share the same perQ data.
*/ */
if ( pCurMsgQ->pQData != pMsgQ->pQData ) if ( pCurMsgQ->pQData != pMsgQ->pQData )
goto CLEANUP; {
QUEUE_Unlock( pMsgQ );
goto error;
}
/* Save current active window */ /* Save current active window */
prev = PERQDATA_GetActiveWnd( pMsgQ->pQData ); prev = PERQDATA_GetActiveWnd( pMsgQ->pQData );
QUEUE_Unlock( pMsgQ );
WINPOS_SetActiveWindow( hwnd, 0, 0 );
CLEANUP:
/* Unlock the queues before returning */
if ( pMsgQ )
QUEUE_Unlock( pMsgQ );
end:
WIN_ReleaseWndPtr(wndPtr); WIN_ReleaseWndPtr(wndPtr);
WINPOS_SetActiveWindow( hwnd, 0, 0 );
return prev; return prev;
error:
WIN_ReleaseWndPtr(wndPtr);
return 0;
} }
@ -1399,7 +1396,6 @@ BOOL WINPOS_ActivateOtherWindow(HWND hwnd)
BOOL WINPOS_ChangeActiveWindow( HWND hWnd, BOOL mouseMsg ) BOOL WINPOS_ChangeActiveWindow( HWND hWnd, BOOL mouseMsg )
{ {
WND *wndPtr; WND *wndPtr;
BOOL retvalue;
HWND hwndActive = 0; HWND hwndActive = 0;
/* Get current active window from the active queue */ /* Get current active window from the active queue */
@ -1425,23 +1421,11 @@ BOOL WINPOS_ChangeActiveWindow( HWND hWnd, BOOL mouseMsg )
WIN_ReleaseWndPtr(wndPtr); WIN_ReleaseWndPtr(wndPtr);
return SendMessageA(hWnd, WM_CHILDACTIVATE, 0, 0L); return SendMessageA(hWnd, WM_CHILDACTIVATE, 0, 0L);
} }
if( hWnd == hwndActive )
{
retvalue = FALSE;
goto end;
}
if( !WINPOS_SetActiveWindow(hWnd ,mouseMsg ,TRUE) )
{
retvalue = FALSE;
goto end;
}
retvalue = TRUE;
end:
WIN_ReleaseWndPtr(wndPtr); WIN_ReleaseWndPtr(wndPtr);
return retvalue;
if( hWnd == hwndActive ) return FALSE;
return WINPOS_SetActiveWindow(hWnd ,mouseMsg ,TRUE);
} }