dca_interface  6.3.4
Example implementation of libCUrl initializations and OpenSSL callbacks for Windows.
// win32 sample initization of libCUrl
// win32 sample setup multi-threaded callbacks
#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;
// since version 1.0.0 openSSL supplies a new callback mechanism for multi-threading
// support. It is used automatically in this sample code
// if USE_OPENSSL_V100_CALLBACKS is defined
//
// on Windows we use the new callbacks for openSSL (compatible to openSSL version 1.0.0 and later)
// on Linux we use the standard callbacks for openSSL (compatible to openSSL version up to 0.9.8)
//
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;
}
}
//
// implementation of static functions and helpers
//
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 * /*file*/, int /*line*/ )
{
if ( S_openSslSyncers && ( n < S_openSslSyncerCount ) ) {
if (mode & CRYPTO_LOCK)
EnterCriticalSection( &( S_openSslSyncers[ n ] ) );
else
LeaveCriticalSection( &( S_openSslSyncers[ n ] ) );
}
}