#include "curl/curl.h"
#include "curl/types.h"
#include "curl/easy.h"
#include "openssl/crypto.h"
#include <windows.h>
static int S_openSslSyncerCount = 0;
static CRITICAL_SECTION* S_openSslSyncers = 0;
void MyInitCUrl()
{
curl_global_init(CURL_GLOBAL_ALL);
}
void MyDeinitCUrl()
{
curl_global_cleanup();
}
void MySetOpenSslCallbacks()
{
if ( S_openSslSyncers )
return;
S_openSslSyncerCount = CRYPTO_num_locks();
if ( S_openSslSyncerCount <= 0 )
return;
S_openSslSyncers = new CRITICAL_SECTION[ S_openSslSyncerCount ];
if ( S_openSslSyncers ) {
int i = 0;
for ( i = 0; i < S_openSslSyncerCount; i++ )
InitializeCriticalSection( &( S_openSslSyncers[ i ] ) );
S_openSsl_setCallbacks( );
}
}
void MyUnsetOpenSslCallbacks()
{
if ( !S_openSslSyncers )
return;
if ( S_openSslSyncers ) {
S_openSsl_unsetCallbacks( );
int i = 0;
for ( i = 0; i < S_openSslSyncerCount; i++ )
DeleteCriticalSection( &( S_openSslSyncers[ i ] ) );
delete [ ] S_openSslSyncers;
S_openSslSyncers = 0;
}
}
static void S_openSsl_setCallbacks( )
{
CRYPTO_THREADID_set_callback( S_openSsl_GetThreadIdCallback );
CRYPTO_set_locking_callback( S_openSsl_LockCallback );
}
static void S_openSsl_unsetCallbacks( )
{
CRYPTO_THREADID_set_callback( 0 );
CRYPTO_set_locking_callback( 0 );
}
static void S_openSsl_GetThreadIdCallback( CRYPTO_THREADID * result )
{
CRYPTO_THREADID_set_numeric( result, ::GetCurrentThreadId( ) );
}
static void S_openSsl_LockCallback( int mode, int n, const char * , int )
{
if ( S_openSslSyncers && ( n < S_openSslSyncerCount ) ) {
if (mode & CRYPTO_LOCK)
EnterCriticalSection( &( S_openSslSyncers[ n ] ) );
else
LeaveCriticalSection( &( S_openSslSyncers[ n ] ) );
}
}