| /* |
| Copyright (C) 2006 Werner Dittmann |
| |
| This program is free software; you can redistribute it and/or modify |
| it under the terms of the GNU General Public License as published by |
| the Free Software Foundation; either version 2, or (at your option) |
| any later version. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with this program; if not, write to the Free Software |
| Foundation, Inc., 59 Temple Place, Boston, MA 02111. |
| */ |
| |
| #include <stdio.h> |
| #include <openssl/evp.h> |
| |
| #include <private.h> |
| |
| #ifdef OPENSSL_SYS_WIN32 |
| #include <windows.h> |
| #endif |
| #if defined SOLARIS && !defined HAVE_PTHREAD_H |
| #include <synch.h> |
| #include <thread.h> |
| #endif |
| #if defined HAVE_PTHREAD_H && !defined SOLARIS |
| #include <pthread.h> |
| #endif |
| |
| static void threadLockSetup(void); |
| static void threadLockCleanup(void); |
| static void myLockingCallback(int, int, const char *, int); |
| |
| /** |
| * Implement the locking callback functions for openSSL. |
| * |
| * Unfortunatly we can't use the Commonc++ Mutex here because the |
| * Mutex may use (for some cases) the Commonc++ Thread class. OpenSSL |
| * does not use this Thread class. |
| */ |
| |
| static int initialized = 0; |
| |
| int initializeOpenSSL () |
| { |
| |
| if (initialized) { |
| return 1; |
| } |
| initialized = 1; |
| threadLockSetup(); |
| return 1; |
| } |
| |
| int finalizeOpenSSL () |
| { |
| if(!initialized) |
| return 1; |
| |
| initialized = 0; |
| threadLockCleanup(); |
| return 1; |
| } |
| |
| #ifdef OPENSSL_SYS_WIN32 |
| |
| static HANDLE *lock_cs; |
| |
| static void threadLockSetup(void) { |
| int i; |
| |
| lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(HANDLE)); |
| for (i = 0; i < CRYPTO_num_locks(); i++) { |
| lock_cs[i] = CreateMutex(NULL,FALSE,NULL); |
| } |
| |
| CRYPTO_set_locking_callback((void (*)(int,int,const char *,int))myLockingCallback); |
| /* id callback defined */ |
| } |
| |
| static void threadLockCleanup(void) { |
| int i; |
| |
| CRYPTO_set_locking_callback(NULL); |
| for (i = 0; i < CRYPTO_num_locks(); i++) { |
| CloseHandle(lock_cs[i]); |
| } |
| OPENSSL_free(lock_cs); |
| } |
| |
| static void myLockingCallback(int mode, int type, const char *file, int line) { |
| if (mode & CRYPTO_LOCK) { |
| WaitForSingleObject(lock_cs[type], INFINITE); |
| } |
| else { |
| ReleaseMutex(lock_cs[type]); |
| } |
| } |
| |
| #endif /* OPENSSL_SYS_WIN32 */ |
| |
| |
| #if defined SOLARIS && !defined HAVE_PTHREAD_H |
| |
| static mutex_t *lock_cs; |
| static long *lock_count; |
| |
| static void threadLockSetup(void) { |
| int i; |
| |
| lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(mutex_t)); |
| lock_count = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long)); |
| for (i = 0; i < CRYPTO_num_locks(); i++) { |
| lock_count[i] = 0; |
| /* rwlock_init(&(lock_cs[i]),USYNC_THREAD,NULL); */ |
| mutex_init(&(lock_cs[i]), USYNC_THREAD, NULL); |
| } |
| CRYPTO_set_locking_callback((void (*)(int, int ,const char *, int))myLockingCallback); |
| } |
| |
| static void threadLockCleanup(void) { |
| int i; |
| |
| CRYPTO_set_locking_callback(NULL); |
| |
| fprintf(stderr,"cleanup\n"); |
| |
| for (i = 0; i < CRYPTO_num_locks(); i++) { |
| /* rwlock_destroy(&(lock_cs[i])); */ |
| mutex_destroy(&(lock_cs[i])); |
| fprintf(stderr,"%8ld:%s\n",lock_count[i],CRYPTO_get_lock_name(i)); |
| } |
| OPENSSL_free(lock_cs); |
| OPENSSL_free(lock_count); |
| } |
| |
| static void myLockingCallback(int mode, int type, const char *file, int line) |
| { |
| #ifdef undef |
| fprintf(stderr,"thread=%4d mode=%s lock=%s %s:%d\n", |
| CRYPTO_thread_id(), |
| (mode&CRYPTO_LOCK)?"l":"u", |
| (type&CRYPTO_READ)?"r":"w",file,line); |
| #endif |
| |
| /* |
| if (CRYPTO_LOCK_SSL_CERT == type) |
| fprintf(stderr,"(t,m,f,l) %ld %d %s %d\n", |
| CRYPTO_thread_id(), |
| mode,file,line); |
| */ |
| if (mode & CRYPTO_LOCK) { |
| mutex_lock(&(lock_cs[type])); |
| lock_count[type]++; |
| } |
| else { |
| mutex_unlock(&(lock_cs[type])); |
| } |
| } |
| |
| static unsigned long solaris_thread_id(void) { |
| unsigned long ret; |
| |
| ret=(unsigned long)thr_self(); |
| return(ret); |
| } |
| #endif /* SOLARIS */ |
| |
| |
| #if defined HAVE_PTHREAD_H && !defined SOLARIS |
| |
| static pthread_mutex_t* lock_cs; |
| static long* lock_count; |
| |
| static void threadLockSetup(void) { |
| int i; |
| |
| lock_cs = (pthread_mutex_t*)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t)); |
| lock_count = (long*)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long)); |
| for (i = 0; i < CRYPTO_num_locks(); i++) { |
| lock_count[i] = 0; |
| pthread_mutex_init(&(lock_cs[i]),NULL); |
| } |
| |
| // CRYPTO_set_id_callback((unsigned long (*)())pthreads_thread_id); |
| CRYPTO_set_locking_callback((void (*)(int, int ,const char *, int))myLockingCallback); |
| } |
| |
| static void threadLockCleanup(void) |
| { |
| int i; |
| |
| CRYPTO_set_locking_callback(NULL); |
| fprintf(stderr,"cleanup\n"); |
| for (i = 0; i < CRYPTO_num_locks(); i++) { |
| pthread_mutex_destroy(&(lock_cs[i])); |
| fprintf(stderr,"%8ld:%s\n",lock_count[i], |
| CRYPTO_get_lock_name(i)); |
| } |
| OPENSSL_free(lock_cs); |
| OPENSSL_free(lock_count); |
| } |
| |
| static void myLockingCallback(int mode, int type, const char *file, |
| int line) { |
| #ifdef undef |
| fprintf(stderr,"thread=%4d mode=%s lock=%s %s:%d\n", |
| CRYPTO_thread_id(), |
| (mode&CRYPTO_LOCK)?"l":"u", |
| (type&CRYPTO_READ)?"r":"w",file,line); |
| #endif |
| if (mode & CRYPTO_LOCK) { |
| pthread_mutex_lock(&(lock_cs[type])); |
| lock_count[type]++; |
| } |
| else { |
| pthread_mutex_unlock(&(lock_cs[type])); |
| } |
| } |
| |
| /* |
| static unsigned long pthreads_thread_id(void) |
| { |
| unsigned long ret; |
| |
| ret = (unsigned long)pthread_self(); |
| return(ret); |
| } |
| */ |
| |
| #endif /* LIBPTHREAD && !SOLARIS */ |