[PATCH] server: Only allocate the required size in get_rawinput_buffer.

Rémi Bernon rbernon at codeweavers.com
Tue Nov 10 07:36:51 CST 2020


Instead of allocating the maximum reply size.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---

CoD: WWII calls this with large buffer and it causes a high load on
wineserver, although there may not even be any message to return.

 server/queue.c | 60 ++++++++++++++++++++++++++++++++------------------
 1 file changed, 38 insertions(+), 22 deletions(-)

diff --git a/server/queue.c b/server/queue.c
index 7e7e6fbdf29..3de4d241b8e 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -3251,19 +3251,13 @@ DECL_HANDLER(get_cursor_history)
             pos[i] = cursor_history[(i + cursor_history_latest) % ARRAY_SIZE(cursor_history)];
 }
 
-DECL_HANDLER(get_rawinput_buffer)
+static void copy_rawinput_buffer( struct thread_input *input, char *reply_buf, data_size_t reply_buf_size, data_size_t *reply_size,
+                                  data_size_t client_buf_size, data_size_t client_elt_size, data_size_t *next_size, unsigned int *count )
 {
-    struct thread_input *input = current->queue->input;
-    data_size_t size = 0, next_size = 0;
+    unsigned int n = 0;
     struct list *ptr;
-    char *buf, *cur;
-    int count = 0;
+    char *reply_ptr = reply_buf;
 
-    if (!req->buffer_size) buf = NULL;
-    else if (!(buf = mem_alloc( get_reply_max_size() )))
-        return;
-
-    cur = buf;
     ptr = list_head( &input->msg_list );
     while (ptr)
     {
@@ -3273,22 +3267,44 @@ DECL_HANDLER(get_rawinput_buffer)
         ptr = list_next( &input->msg_list, ptr );
         if (msg->msg != WM_INPUT) continue;
 
-        next_size = req->rawinput_size;
-        if (size + next_size > req->buffer_size) break;
-        if (cur + sizeof(*data) > buf + get_reply_max_size()) break;
+        if (next_size) *next_size = client_elt_size;
+        if (client_buf_size < client_elt_size) break;
+        if (reply_buf_size < sizeof(*data)) break;
 
-        memcpy(cur, data, sizeof(*data));
-        list_remove( &msg->entry );
-        free_message( msg );
+        if (reply_buf)
+        {
+            memcpy( reply_ptr, data, sizeof(*data) );
+            list_remove( &msg->entry );
+            free_message( msg );
+        }
 
-        size += next_size;
-        cur += sizeof(*data);
-        count++;
+        client_buf_size -= client_elt_size;
+        reply_buf_size -= sizeof(*data);
+        reply_ptr += sizeof(*data);
+        n++;
     }
 
-    reply->next_size = next_size;
-    reply->count = count;
-    set_reply_data_ptr( buf, cur - buf );
+    if (reply_size) *reply_size = reply_ptr - reply_buf;
+    if (count) *count = n;
+}
+
+DECL_HANDLER(get_rawinput_buffer)
+{
+    struct thread_input *input = current->queue->input;
+    data_size_t reply_size;
+    char *reply_buf;
+
+    reply->next_size = 0;
+    reply->count = 0;
+
+    copy_rawinput_buffer( input, NULL, get_reply_max_size(), &reply_size, req->buffer_size,
+                          req->rawinput_size, &reply->next_size, &reply->count );
+
+    if (!req->buffer_size || !reply_size) return;
+    if (!(reply_buf = set_reply_data_size( reply_size ))) return;
+
+    copy_rawinput_buffer( input, reply_buf, reply_size, NULL, req->buffer_size,
+                          req->rawinput_size, NULL, NULL );
 }
 
 DECL_HANDLER(update_rawinput_devices)
-- 
2.29.2




More information about the wine-devel mailing list