A couple of optimizations to avoid some server calls in WIN_FindWndPtr
and related functions.
diff --git a/dlls/user/msg16.c b/dlls/user/msg16.c
index c827107..2ed9979 100644
--- a/dlls/user/msg16.c
+++ b/dlls/user/msg16.c
@@ -25,8 +25,7 @@
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 8cc7bdb..8d41209 100644
--- a/include/win.h
+++ b/include/win.h
@@ -86,6 +86,8 @@
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 18ecc74..c94d2d4 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -40,6 +40,10 @@
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 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 a87287c..010d2ed 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -42,6 +42,10 @@
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 @@
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 93a4f36..66d58f9 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -1722,7 +1722,7 @@
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 e31fb16..e28189c 100644
--- a/server/user.c
+++ b/server/user.c
@@ -19,13 +19,9 @@
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 @@
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 @@
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 1a68a22..638e474 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -506,7 +506,7 @@
/* 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 f0651a2..0f760db 100644
--- a/windows/timer.c
+++ b/windows/timer.c
@@ -104,7 +104,7 @@
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 a587cae..a080870 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -4,6 +4,7 @@
* Copyright 1993, 1994 Alexandre Julliard
*/
+#include <assert.h>
#include <stdlib.h>
#include <string.h>
#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 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 @@
{
BOOL res;
user_handle_t handle = 0;
+ WORD index;
WND *win = HeapAlloc( GetProcessHeap(), 0, size );
if (!win) return NULL;
@@ -99,7 +104,9 @@
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 *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 @@
/***********************************************************************
* 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 @@
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 @@
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 @@
{
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 @@
{
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 @@
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 @@
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 @@
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 1779348..285f5b5 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -375,8 +375,8 @@
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 @@
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 );
-
- WINPOS_SetActiveWindow( hwnd, 0, 0 );
-
-CLEANUP:
- /* Unlock the queues before returning */
- if ( pMsgQ )
- QUEUE_Unlock( pMsgQ );
-
-end:
+ QUEUE_Unlock( pMsgQ );
WIN_ReleaseWndPtr(wndPtr);
+ WINPOS_SetActiveWindow( hwnd, 0, 0 );
return prev;
+
+ error:
+ WIN_ReleaseWndPtr(wndPtr);
+ return 0;
}
@@ -1399,7 +1396,6 @@
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 @@
WIN_ReleaseWndPtr(wndPtr);
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);
- return retvalue;
+
+ if( hWnd == hwndActive ) return FALSE;
+
+ return WINPOS_SetActiveWindow(hWnd ,mouseMsg ,TRUE);
}