From 18d0ea3aec53d25ba5673576093c1acbc9289f9d Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Tue, 3 Mar 2015 19:20:40 +0100
Subject: ws2_32: Reuse old async ws2_async_io structures if possible.

---
 dlls/ws2_32/socket.c | 28 +++++++++++++++++++++-------
 1 file changed, 21 insertions(+), 7 deletions(-)

diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index 8f11dd8ce7..ae20bd03f3 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -476,6 +476,7 @@ struct ws2_async_io
 {
     async_callback_t *callback; /* must be the first field */
     struct ws2_async_io *next;
+    DWORD                size;
 };
 
 struct ws2_async_shutdown
@@ -551,17 +552,30 @@ static struct ws2_async_io *alloc_async_io( DWORD size, async_callback_t callbac
 {
     /* first free remaining previous fileinfos */
 
-    struct ws2_async_io *io = InterlockedExchangePointer( (void **)&async_io_freelist, NULL );
+    struct ws2_async_io *old_io = InterlockedExchangePointer( (void **)&async_io_freelist, NULL );
+    struct ws2_async_io *io = NULL;
 
-    while (io)
+    while (old_io)
     {
-        struct ws2_async_io *next = io->next;
-        HeapFree( GetProcessHeap(), 0, io );
-        io = next;
+        if (!io && old_io->size >= size && old_io->size <= max(4096, 4 * size))
+        {
+            io     = old_io;
+            size   = old_io->size;
+            old_io = old_io->next;
+        }
+        else
+        {
+            struct ws2_async_io *next = old_io->next;
+            HeapFree( GetProcessHeap(), 0, old_io );
+            old_io = next;
+        }
     }
 
-    io = HeapAlloc( GetProcessHeap(), 0, size );
-    if (io) io->callback = callback;
+    if (io || (io = HeapAlloc( GetProcessHeap(), 0, size )))
+    {
+        io->callback = callback;
+        io->size = size;
+    }
     return io;
 }
 
-- 
2.11.0

