Juan Lang : wininet: Set callbacks needed by OpenSSL for multithreaded use.

Alexandre Julliard julliard at winehq.org
Fri Oct 2 11:02:25 CDT 2009


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

Author: Juan Lang <juan.lang at gmail.com>
Date:   Fri Oct  2 07:47:48 2009 -0700

wininet: Set callbacks needed by OpenSSL for multithreaded use.

---

 dlls/wininet/netconnection.c |   46 ++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 46 insertions(+), 0 deletions(-)

diff --git a/dlls/wininet/netconnection.c b/dlls/wininet/netconnection.c
index 1a9d7a2..97c764f 100644
--- a/dlls/wininet/netconnection.c
+++ b/dlls/wininet/netconnection.c
@@ -138,11 +138,29 @@ MAKE_FUNCPTR(SSL_CTX_set_default_verify_paths);
 
 /* OpenSSL's libcrypto functions that we use */
 MAKE_FUNCPTR(BIO_new_fp);
+MAKE_FUNCPTR(CRYPTO_num_locks);
+MAKE_FUNCPTR(CRYPTO_set_id_callback);
+MAKE_FUNCPTR(CRYPTO_set_locking_callback);
 MAKE_FUNCPTR(ERR_get_error);
 MAKE_FUNCPTR(ERR_error_string);
 MAKE_FUNCPTR(i2d_X509);
 #undef MAKE_FUNCPTR
 
+static CRITICAL_SECTION *ssl_locks;
+
+static unsigned long ssl_thread_id(void)
+{
+    return GetCurrentThreadId();
+}
+
+static void ssl_lock_callback(int mode, int type, const char *file, int line)
+{
+    if (mode & CRYPTO_LOCK)
+        EnterCriticalSection(&ssl_locks[type]);
+    else
+        LeaveCriticalSection(&ssl_locks[type]);
+}
+
 #endif
 
 BOOL NETCON_init(WININET_NETCONNECTION *connection, BOOL useSSL)
@@ -152,6 +170,8 @@ BOOL NETCON_init(WININET_NETCONNECTION *connection, BOOL useSSL)
     if (useSSL)
     {
 #if defined(SONAME_LIBSSL) && defined(SONAME_LIBCRYPTO)
+        int i;
+
         TRACE("using SSL connection\n");
         EnterCriticalSection(&init_ssl_cs);
 	if (OpenSSL_ssl_handle) /* already initialized everything */
@@ -219,6 +239,9 @@ BOOL NETCON_init(WININET_NETCONNECTION *connection, BOOL useSSL)
         return FALSE; \
     }
 	DYNCRYPTO(BIO_new_fp);
+	DYNCRYPTO(CRYPTO_num_locks);
+	DYNCRYPTO(CRYPTO_set_id_callback);
+	DYNCRYPTO(CRYPTO_set_locking_callback);
 	DYNCRYPTO(ERR_get_error);
 	DYNCRYPTO(ERR_error_string);
 	DYNCRYPTO(i2d_X509);
@@ -238,6 +261,19 @@ BOOL NETCON_init(WININET_NETCONNECTION *connection, BOOL useSSL)
             LeaveCriticalSection(&init_ssl_cs);
             return FALSE;
         }
+
+        pCRYPTO_set_id_callback(ssl_thread_id);
+        ssl_locks = HeapAlloc(GetProcessHeap(), 0,
+                pCRYPTO_num_locks() * sizeof(CRITICAL_SECTION));
+        if (!ssl_locks)
+        {
+            INTERNET_SetLastError(ERROR_OUTOFMEMORY);
+            LeaveCriticalSection(&init_ssl_cs);
+            return FALSE;
+        }
+        for (i = 0; i < pCRYPTO_num_locks(); i++)
+            InitializeCriticalSection(&ssl_locks[i]);
+        pCRYPTO_set_locking_callback(ssl_lock_callback);
         LeaveCriticalSection(&init_ssl_cs);
 #else
 	FIXME("can't use SSL, not compiled in.\n");
@@ -252,7 +288,17 @@ void NETCON_unload(void)
 {
 #if defined(SONAME_LIBSSL) && defined(SONAME_LIBCRYPTO)
     if (OpenSSL_crypto_handle)
+    {
+        if (ssl_locks)
+        {
+            int i;
+
+            for (i = 0; i < pCRYPTO_num_locks(); i++)
+                DeleteCriticalSection(&ssl_locks[i]);
+            HeapFree(GetProcessHeap(), 0, ssl_locks);
+        }
         wine_dlclose(OpenSSL_crypto_handle, NULL, 0);
+    }
     if (OpenSSL_ssl_handle)
     {
         if (ctx)




More information about the wine-cvs mailing list