blob: 17961c3cc41255fbdcc18ec10e6c2d5e50e9170a [file] [log] [blame]
/*
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 <libzrtpcpp-config.h>
#if defined(_MSC_VER) || defined(WIN32) || defined(_WIN32)
#undef _MSWINDOWS_
#define _MSWINDOWS_
#include <windows.h>
#endif
#if defined SOLARIS && !defined HAVE_PTHREAD_H
#include <synch.h>
#include <thread.h>
#endif
#if !defined(_MSWINDOWS_) && !defined SOLARIS
#include <pthread.h>
#endif
#ifdef const
#undef const
#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 _MSWINDOWS_
#define __LOCKING
static HANDLE *lock_cs;
static void threadLockSetup(void) {
int i;
lock_cs=(HANDLE*)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 && !defined(_MSWINDOWS)
#define __LOCKING
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 */
#ifndef __LOCKING
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