[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