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

Alexandre Julliard julliard at winehq.org
Thu Oct 8 08:57:12 CDT 2009


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

Author: Juan Lang <juan.lang at gmail.com>
Date:   Wed Oct  7 08:36:04 2009 -0700

winhttp: Set callbacks needed by OpenSSL for multithreaded use.

---

 dlls/winhttp/net.c |   49 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 49 insertions(+), 0 deletions(-)

diff --git a/dlls/winhttp/net.c b/dlls/winhttp/net.c
index 7ab9944..6e54348 100644
--- a/dlls/winhttp/net.c
+++ b/dlls/winhttp/net.c
@@ -111,11 +111,29 @@ MAKE_FUNCPTR( SSL_get_peer_certificate );
 MAKE_FUNCPTR( SSL_CTX_set_default_verify_paths );
 
 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
 
 /* translate a unix error code into a winsock error code */
@@ -187,6 +205,10 @@ static int sock_get_error( int err )
 
 BOOL netconn_init( netconn_t *conn, BOOL secure )
 {
+#if defined(SONAME_LIBSSL) && defined(SONAME_LIBCRYPTO)
+    int i;
+#endif
+
     conn->socket = -1;
     if (!secure) return TRUE;
 
@@ -245,6 +267,9 @@ BOOL netconn_init( netconn_t *conn, BOOL secure )
         return FALSE; \
     }
     LOAD_FUNCPTR( BIO_new_fp );
+    LOAD_FUNCPTR( CRYPTO_num_locks );
+    LOAD_FUNCPTR( CRYPTO_set_id_callback );
+    LOAD_FUNCPTR( CRYPTO_set_locking_callback );
     LOAD_FUNCPTR( ERR_get_error );
     LOAD_FUNCPTR( ERR_error_string );
     LOAD_FUNCPTR( i2d_X509 );
@@ -263,6 +288,20 @@ BOOL netconn_init( netconn_t *conn, BOOL secure )
         LeaveCriticalSection( &init_ssl_cs );
         return FALSE;
     }
+
+    pCRYPTO_set_id_callback(ssl_thread_id);
+    ssl_locks = HeapAlloc(GetProcessHeap(), 0,
+            pCRYPTO_num_locks() * sizeof(HANDLE));
+    if (!ssl_locks)
+    {
+        set_last_error( 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
     WARN("SSL support not compiled in.\n");
@@ -276,7 +315,17 @@ void netconn_unload( void )
 {
 #if defined(SONAME_LIBSSL) && defined(SONAME_LIBCRYPTO)
     if (libcrypto_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( libcrypto_handle, NULL, 0 );
+    }
     if (libssl_handle)
     {
         if (ctx)




More information about the wine-cvs mailing list