Alexandre Julliard : user32: Use a local buffer in peek_message to save a server call for small buffer sizes .

Alexandre Julliard julliard at winehq.org
Wed Oct 29 09:39:25 CDT 2008


Module: wine
Branch: master
Commit: 7804129e68a0b25549b729854c15706827140b46
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=7804129e68a0b25549b729854c15706827140b46

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Wed Oct 29 12:13:51 2008 +0100

user32: Use a local buffer in peek_message to save a server call for small buffer sizes.

---

 dlls/user32/message.c |   95 +++++++++++++++++++++++-------------------------
 1 files changed, 46 insertions(+), 49 deletions(-)

diff --git a/dlls/user32/message.c b/dlls/user32/message.c
index 7330030..aeda7b3 100644
--- a/dlls/user32/message.c
+++ b/dlls/user32/message.c
@@ -2029,54 +2029,53 @@ static BOOL peek_message( MSG *msg, HWND hwnd, UINT first, UINT last, UINT flags
     struct user_thread_info *thread_info = get_user_thread_info();
     struct received_message_info info, *old_info;
     unsigned int hw_id = 0;  /* id of previous hardware message */
+    char local_buffer[256];
+    void *buffer = local_buffer;
+    size_t buffer_size = sizeof(local_buffer);
 
     if (!first && !last) last = ~0;
 
     for (;;)
     {
         NTSTATUS res;
-        void *buffer = NULL;
-        size_t size = 0, buffer_size = 0;
+        size_t size = 0;
 
-        do  /* loop while buffer is too small */
+        SERVER_START_REQ( get_message )
         {
-            if (buffer_size && !(buffer = HeapAlloc( GetProcessHeap(), 0, buffer_size )))
-                return FALSE;
-            SERVER_START_REQ( get_message )
+            req->flags     = flags;
+            req->get_win   = hwnd;
+            req->get_first = first;
+            req->get_last  = last;
+            req->hw_id     = hw_id;
+            req->wake_mask = changed_mask & (QS_SENDMESSAGE | QS_SMRESULT);
+            req->changed_mask = changed_mask;
+            wine_server_set_reply( req, buffer, buffer_size );
+            if (!(res = wine_server_call( req )))
             {
-                req->flags     = flags;
-                req->get_win   = hwnd;
-                req->get_first = first;
-                req->get_last  = last;
-                req->hw_id     = hw_id;
-                req->wake_mask = changed_mask & (QS_SENDMESSAGE | QS_SMRESULT);
-                req->changed_mask = changed_mask;
-                if (buffer_size) wine_server_set_reply( req, buffer, buffer_size );
-                if (!(res = wine_server_call( req )))
-                {
-                    size = wine_server_reply_size( reply );
-                    info.type        = reply->type;
-                    info.msg.hwnd    = reply->win;
-                    info.msg.message = reply->msg;
-                    info.msg.wParam  = reply->wparam;
-                    info.msg.lParam  = reply->lparam;
-                    info.msg.time    = reply->time;
-                    info.msg.pt.x    = reply->x;
-                    info.msg.pt.y    = reply->y;
-                    hw_id            = reply->hw_id;
-                    extra_info       = reply->info;
-                    thread_info->active_hooks = reply->active_hooks;
-                }
-                else
-                {
-                    HeapFree( GetProcessHeap(), 0, buffer );
-                    buffer_size = reply->total;
-                }
+                size = wine_server_reply_size( reply );
+                info.type        = reply->type;
+                info.msg.hwnd    = reply->win;
+                info.msg.message = reply->msg;
+                info.msg.wParam  = reply->wparam;
+                info.msg.lParam  = reply->lparam;
+                info.msg.time    = reply->time;
+                info.msg.pt.x    = reply->x;
+                info.msg.pt.y    = reply->y;
+                hw_id            = reply->hw_id;
+                extra_info       = reply->info;
+                thread_info->active_hooks = reply->active_hooks;
             }
-            SERVER_END_REQ;
-        } while (res == STATUS_BUFFER_OVERFLOW);
+            else buffer_size = reply->total;
+        }
+        SERVER_END_REQ;
 
-        if (res) return FALSE;
+        if (res)
+        {
+            if (buffer != local_buffer) HeapFree( GetProcessHeap(), 0, buffer );
+            if (res != STATUS_BUFFER_OVERFLOW) return FALSE;
+            if (!(buffer = HeapAlloc( GetProcessHeap(), 0, buffer_size ))) return FALSE;
+            continue;
+        }
 
         TRACE( "got type %d msg %x (%s) hwnd %p wp %lx lp %lx\n",
                info.type, info.msg.message,
@@ -2098,16 +2097,16 @@ static BOOL peek_message( MSG *msg, HWND hwnd, UINT first, UINT last, UINT flags
         case MSG_CALLBACK_RESULT:
             if (size >= sizeof(struct callback_msg_data))
             {
-                const struct callback_msg_data *data = (const struct callback_msg_data *)buffer;
+                const struct callback_msg_data *data = buffer;
                 call_sendmsg_callback( data->callback, info.msg.hwnd,
                                        info.msg.message, data->data, data->result );
             }
-            goto next;
+            continue;
         case MSG_WINEVENT:
             if (size >= sizeof(struct winevent_msg_data))
             {
                 WINEVENTPROC hook_proc;
-                const struct winevent_msg_data *data = (const struct winevent_msg_data *)buffer;
+                const struct winevent_msg_data *data = buffer;
 
                 hook_proc = data->hook_proc;
                 size -= sizeof(*data);
@@ -2121,7 +2120,7 @@ static BOOL peek_message( MSG *msg, HWND hwnd, UINT first, UINT last, UINT flags
                     if (!(hook_proc = get_hook_proc( hook_proc, module )))
                     {
                         ERR( "invalid winevent hook module name %s\n", debugstr_w(module) );
-                        goto next;
+                        continue;
                     }
                 }
 
@@ -2140,7 +2139,7 @@ static BOOL peek_message( MSG *msg, HWND hwnd, UINT first, UINT last, UINT flags
                              data->hook, info.msg.message, info.msg.hwnd, info.msg.wParam,
                              info.msg.lParam, data->tid, info.msg.time);
             }
-            goto next;
+            continue;
         case MSG_OTHER_PROCESS:
             info.flags = ISMEX_SEND;
             if (!unpack_message( info.msg.hwnd, info.msg.message, &info.msg.wParam,
@@ -2148,7 +2147,7 @@ static BOOL peek_message( MSG *msg, HWND hwnd, UINT first, UINT last, UINT flags
             {
                 /* ignore it */
                 reply_message( &info, 0, TRUE );
-                goto next;
+                continue;
             }
             break;
         case MSG_HARDWARE:
@@ -2156,7 +2155,7 @@ static BOOL peek_message( MSG *msg, HWND hwnd, UINT first, UINT last, UINT flags
                                            hwnd, first, last, flags & PM_REMOVE ))
             {
                 TRACE("dropping msg %x\n", info.msg.message );
-                goto next;  /* ignore it */
+                continue;  /* ignore it */
             }
             thread_info->GetMessagePosVal = MAKELONG( info.msg.pt.x, info.msg.pt.y );
             /* fall through */
@@ -2169,20 +2168,20 @@ static BOOL peek_message( MSG *msg, HWND hwnd, UINT first, UINT last, UINT flags
                 else
                     peek_message( msg, info.msg.hwnd, info.msg.message,
                                   info.msg.message, flags | PM_REMOVE, changed_mask );
-                goto next;
+                continue;
             }
 	    if (info.msg.message >= WM_DDE_FIRST && info.msg.message <= WM_DDE_LAST)
 	    {
 		if (!unpack_dde_message( info.msg.hwnd, info.msg.message, &info.msg.wParam,
                                          &info.msg.lParam, &buffer, size ))
-                    goto next;  /* ignore it */
+                    continue;  /* ignore it */
 	    }
             *msg = info.msg;
             msg->pt.x = (short)LOWORD( thread_info->GetMessagePosVal );
             msg->pt.y = (short)HIWORD( thread_info->GetMessagePosVal );
             thread_info->GetMessageTimeVal = info.msg.time;
             thread_info->GetMessageExtraInfoVal = extra_info;
-            HeapFree( GetProcessHeap(), 0, buffer );
+            if (buffer != local_buffer) HeapFree( GetProcessHeap(), 0, buffer );
             HOOK_CallHooks( WH_GETMESSAGE, HC_ACTION, flags & PM_REMOVE, (LPARAM)msg, TRUE );
             return TRUE;
         }
@@ -2198,8 +2197,6 @@ static BOOL peek_message( MSG *msg, HWND hwnd, UINT first, UINT last, UINT flags
 
         /* if some PM_QS* flags were specified, only handle sent messages from now on */
         if (HIWORD(flags) && !changed_mask) flags = PM_QS_SENDMESSAGE | LOWORD(flags);
-    next:
-        HeapFree( GetProcessHeap(), 0, buffer );
     }
 }
 




More information about the wine-cvs mailing list