Jacek Caban : winhttp: Periodically free outdated connections.

Alexandre Julliard julliard at winehq.org
Tue Jul 18 13:58:54 CDT 2017


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Tue Jul 18 00:25:20 2017 +0200

winhttp: Periodically free outdated connections.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Hans Leidekker <hans at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/winhttp/main.c            |  8 ++---
 dlls/winhttp/request.c         | 67 ++++++++++++++++++++++++++++++++++++++++++
 dlls/winhttp/winhttp_private.h |  3 ++
 3 files changed, 74 insertions(+), 4 deletions(-)

diff --git a/dlls/winhttp/main.c b/dlls/winhttp/main.c
index cd2d114..a63f28c 100644
--- a/dlls/winhttp/main.c
+++ b/dlls/winhttp/main.c
@@ -30,7 +30,7 @@
 #include "wine/debug.h"
 #include "winhttp_private.h"
 
-static HINSTANCE instance;
+HINSTANCE winhttp_instance;
 
 WINE_DEFAULT_DEBUG_CHANNEL(winhttp);
 
@@ -42,7 +42,7 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
     switch(fdwReason)
     {
     case DLL_PROCESS_ATTACH:
-        instance = hInstDLL;
+        winhttp_instance = hInstDLL;
         DisableThreadLibraryCalls(hInstDLL);
         break;
     case DLL_PROCESS_DETACH:
@@ -169,7 +169,7 @@ HRESULT WINAPI DllCanUnloadNow(void)
  */
 HRESULT WINAPI DllRegisterServer(void)
 {
-    return __wine_register_resources( instance );
+    return __wine_register_resources( winhttp_instance );
 }
 
 /***********************************************************************
@@ -177,5 +177,5 @@ HRESULT WINAPI DllRegisterServer(void)
  */
 HRESULT WINAPI DllUnregisterServer(void)
 {
-    return __wine_unregister_resources( instance );
+    return __wine_unregister_resources( winhttp_instance );
 }
diff --git a/dlls/winhttp/request.c b/dlls/winhttp/request.c
index a9f44eaf..47cc906 100644
--- a/dlls/winhttp/request.c
+++ b/dlls/winhttp/request.c
@@ -43,6 +43,8 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(winhttp);
 
+#define DEFAULT_KEEP_ALIVE_TIMEOUT 30000
+
 static const WCHAR attr_accept[] = {'A','c','c','e','p','t',0};
 static const WCHAR attr_accept_charset[] = {'A','c','c','e','p','t','-','C','h','a','r','s','e','t', 0};
 static const WCHAR attr_accept_encoding[] = {'A','c','c','e','p','t','-','E','n','c','o','d','i','n','g',0};
@@ -1016,12 +1018,77 @@ void release_host( host_t *host )
     heap_free( host );
 }
 
+static BOOL connection_collector_running;
+
+static DWORD WINAPI connection_collector(void *arg)
+{
+    unsigned int remaining_connections;
+    netconn_t *netconn, *next_netconn;
+    host_t *host, *next_host;
+    ULONGLONG now;
+
+    do
+    {
+        /* FIXME: Use more sophisticated method */
+        Sleep(5000);
+        remaining_connections = 0;
+        now = GetTickCount64();
+
+        EnterCriticalSection(&connection_pool_cs);
+
+        LIST_FOR_EACH_ENTRY_SAFE(host, next_host, &connection_pool, host_t, entry)
+        {
+            LIST_FOR_EACH_ENTRY_SAFE(netconn, next_netconn, &host->connections, netconn_t, entry)
+            {
+                if (netconn->keep_until < now)
+                {
+                    TRACE("freeing %p\n", netconn);
+                    list_remove(&netconn->entry);
+                    netconn_close(netconn);
+                }
+                else
+                {
+                    remaining_connections++;
+                }
+            }
+        }
+
+        if (!remaining_connections) connection_collector_running = FALSE;
+
+        LeaveCriticalSection(&connection_pool_cs);
+    } while(remaining_connections);
+
+    FreeLibraryAndExitThread( winhttp_instance, 0 );
+}
+
 static void cache_connection( netconn_t *netconn )
 {
     TRACE( "caching connection %p\n", netconn );
 
     EnterCriticalSection( &connection_pool_cs );
+
+    netconn->keep_until = GetTickCount64() + DEFAULT_KEEP_ALIVE_TIMEOUT;
     list_add_head( &netconn->host->connections, &netconn->entry );
+
+    if (!connection_collector_running)
+    {
+        HMODULE module;
+        HANDLE thread;
+
+        GetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (const WCHAR*)winhttp_instance, &module );
+
+        thread = CreateThread(NULL, 0, connection_collector, NULL, 0, NULL);
+        if (thread)
+        {
+            CloseHandle( thread );
+            connection_collector_running = TRUE;
+        }
+        else
+        {
+            FreeLibrary( winhttp_instance );
+        }
+    }
+
     LeaveCriticalSection( &connection_pool_cs );
 }
 
diff --git a/dlls/winhttp/winhttp_private.h b/dlls/winhttp/winhttp_private.h
index 6d27f22..dd8c4ef 100644
--- a/dlls/winhttp/winhttp_private.h
+++ b/dlls/winhttp/winhttp_private.h
@@ -143,6 +143,7 @@ typedef struct
     struct sockaddr_storage sockaddr;
     BOOL secure; /* SSL active on connection? */
     host_t *host;
+    ULONGLONG keep_until;
     CtxtHandle ssl_ctx;
     SecPkgContext_StreamSizes ssl_sizes;
     char *ssl_buf;
@@ -392,4 +393,6 @@ static inline char *strdupWA_sized( const WCHAR *src, DWORD size )
     return dst;
 }
 
+extern HINSTANCE winhttp_instance DECLSPEC_HIDDEN;
+
 #endif /* _WINE_WINHTTP_PRIVATE_H_ */




More information about the wine-cvs mailing list