libssh2在多线程使用时遇到的openssl线程安全问题如何加回调函数?

luomg 发布于 2015/03/10 11:26
阅读 1K+
收藏 0
libssh2讨论群:229805918
邮箱:armfyy@163.com
关键字:libssh2,多线程,openssl,ssh2,线程安全

      在使用libssh2时,使用多线程方式出现程序崩溃,经过查询发现是openssl不加回调函数不是线程安全的,
但是我加了以后还是出现程序崩溃,现把代码贴上来希望各位能帮忙分析i一下是哪儿有问题?
   #include "main.h"

#define OPENSSL_THREAD_DEFINES
#include <openssl/buffer.h>
#include <openssl/crypto.h>
#include <openssl/opensslconf.h>

#if defined(OPENSSL_THREADS)
#include <pthread.h>
#endif



#ifndef OPENSSL_VERSION_1_0_0
    #define OPENSSL_VERSION_1_0_0 0x10000000L
#endif

#if OPENSSL_VERSION_NUMBER >= OPENSSL_VERSION_1_0_0
void ssl_threadid_function_callback(CRYPTO_THREADID* id);
#else
unsigned long ssl_threadid_function_callback_deprecated();
#endif

#define  THREAD_MAX  3

void ssl_lock_callback(int mode, int type,const char *file, int line);
void thread_setup(void);

static pthread_mutex_t* ssl_locks;

void thread_setup(void)
{
     int i =0 ;
     ssl_locks = calloc(CRYPTO_num_locks(), sizeof(pthread_mutex_t));

     for ( i=0; i< CRYPTO_num_locks(); i++) {
         pthread_mutex_init(&ssl_locks,NULL);
         }
     
     #if OPENSSL_VERSION_NUMBER >= OPENSSL_VERSION_1_0_0
CRYPTO_THREADID_set_callback(ssl_threadid_function_callback);
     #else
          CRYPTO_set_id_callback(ssl_threadid_function_callback_deprecated);
     #endif
    
     CRYPTO_set_locking_callback(ssl_lock_callback);

     #if OPENSSL_VERSION_NUMBER >= OPENSSL_VERSION_1_0_0
         CRYPTO_THREADID_set_callback(ssl_threadid_function_callback);
     #else
         CRYPTO_set_id_callback(NULL);
     #endif
         CRYPTO_set_locking_callback(NULL);

        //printf("ver:%x\n",OPENSSL_VERSION_NUMBER);    
  
}

#if OPENSSL_VERSION_NUMBER >= OPENSSL_VERSION_1_0_0
void ssl_threadid_function_callback(CRYPTO_THREADID* id) {
    CRYPTO_THREADID_set_numeric(id, (unsigned long)pthread_self());
}
#else
unsigned long ssl_threadid_function_callback_deprecated() {
    return (unsigned long)pthread_self();
}
#endif

void ssl_lock_callback(int mode, int type,const char *file, int line) {
    if (mode & CRYPTO_LOCK) {
        pthread_mutex_lock(& ssl_locks[type]);
        //printf("ssl locked: [type] %d, [file] %s, [line] %d", type, file, line);
    } else {
        pthread_mutex_unlock(&(ssl_locks[type]));
       // printf("ssl unlock: [type] %d, [file] %s, [line] %d", type, file, line);
    }
}

int thread_create(void)
{
        int ret;
        int  i=0;

        memset(&thread, 0, sizeof(thread));          //comment1

        for(i =0 ; i < THREAD_MAX ; i++)
        {
        if((ret = pthread_create(&thread[0], NULL, thread_ssh, NULL)) != 0)  //comment2    
        {
                 fprintf(stderr,"thread create failed\n");
        }
        else{
                fprintf(stderr,"%d thread start\n",i);
              

        }

        
        }

        return  0;
}

int threadwait(void)
{
        int i =0 ;

        for(i=0; i<THREAD_MAX; i++)
        {
        if(thread !=0)            {             //comment4                    
       
                pthread_join(thread,NULL);
                fprintf(stderr,"%i thread end\n",i);
          }
        }
        return  0;
}

int main()
{

        thread_setup();
        thread_create();
        threadwait();

       for ( i=0; i < CRYPTO_num_locks(); i++) {
         pthread_mutex_destroy(&(ssl_locks));
         }
   
    free(ssl_locks);
        return 0;
}

加载中
返回顶部
顶部