dca_interface  6.3.4
Example implementation of libCUrl initializations and OpenSSL callbacks for Linux.
// linux sample initization of libCUrl
// linux sample setup multi-threaded callbacks
#include <curl/curl.h>
#include <curl/types.h>
#include <curl/easy.h>
#include <openssl/crypto.h>
#include <pthread.h>
static int S_openSslSyncerCount = 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)
//
static unsigned long S_openSsl_GetThreadIdCallback( )
{
return ( ( unsigned long )( ::GetCurrentThreadId( ) ) );
}
static pthread_mutex_t* S_openSslSyncers = 0;
static unsigned long S_openSsl_GetThreadIdCallback( )
{
return ( ( unsigned long )( pthread_self( ) ) );
}
static void S_openSsl_LockCallback( int mode, int n, const char * /*file*/, int /*line*/ )
{
if ( S_openSslSyncers && ( n < S_openSslSyncerCount ) ) {
if (mode & CRYPTO_LOCK) {
// lock
pthread_mutex_lock( &( S_openSslSyncers[ n ] ) );
}
else {
// unlock
pthread_mutex_unlock( &( S_openSslSyncers[ n ] ) );
}
}
}
static void S_openSsl_setCallbacks( )
{
CRYPTO_set_id_callback( S_openSsl_GetThreadIdCallback );
CRYPTO_set_locking_callback( S_openSsl_LockCallback );
}
static void S_openSsl_unsetCallbacks( )
{
CRYPTO_set_id_callback( 0 );
CRYPTO_set_locking_callback( 0 );
}
// C-interface
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 pthread_mutex_t[ S_openSslSyncerCount ];
if ( S_openSslSyncers ) {
int i = 0;
for ( i = 0; i < S_openSslSyncerCount; i++ )
pthread_mutex_init( &( S_openSslSyncers[ i ] ), NULL );
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++ )
pthread_mutex_destroy( &( S_openSslSyncers[ i ] ) );
delete [ ] S_openSslSyncers;
S_openSslSyncers = 0;
}
}