From f7842e3a4b9acea2126ff725f993c299aef0e6db Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Mon, 6 Sep 2010 14:28:38 +0200 Subject: misc: Rename libssh/ to src/ --- src/threads.c | 159 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 src/threads.c (limited to 'src/threads.c') diff --git a/src/threads.c b/src/threads.c new file mode 100644 index 00000000..7cac6dbf --- /dev/null +++ b/src/threads.c @@ -0,0 +1,159 @@ +/* + * This file is part of the SSH Library + * + * Copyright (c) 2010 by Aris Adamantiadis + * + * The SSH Library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * The SSH Library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the SSH Library; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +/** + * @defgroup libssh_threads Threading with libssh + * @ingroup libssh + * + * Threading with libssh + * @{ + */ + +#include "libssh/priv.h" +#include "libssh/threads.h" + +#ifndef _WIN32 + +#ifndef HAVE_PTHREAD +#warning "You do not have any threading library installed. If the linked" +#warning "application doesn't provide the threading callbacks, you're screwed" +#endif + + +#ifdef HAVE_PTHREAD + +#include +#include +SSH_THREADS_PTHREAD(ssh_pthread_user_callbacks); +#endif /* HAVE_PTHREAD */ +#endif /* _WIN32 */ + +static struct ssh_threads_callbacks_struct *user_callbacks; + +#ifdef HAVE_LIBGCRYPT + +/* Libgcrypt specific way of handling thread callbacks */ + +static struct gcry_thread_cbs gcrypt_threads_callbacks; + +static int libgcrypt_thread_init(void){ + if(user_callbacks == NULL) + return SSH_ERROR; + gcrypt_threads_callbacks.option= GCRY_THREAD_OPTION_VERSION << 8 || GCRY_THREAD_OPTION_USER; + gcrypt_threads_callbacks.mutex_init=user_callbacks->mutex_init; + gcrypt_threads_callbacks.mutex_destroy=user_callbacks->mutex_destroy; + gcrypt_threads_callbacks.mutex_lock=user_callbacks->mutex_lock; + gcrypt_threads_callbacks.mutex_unlock=user_callbacks->mutex_unlock; + gcry_control(GCRYCTL_SET_THREAD_CBS, &gcrypt_threads_callbacks); + return SSH_OK; +} +#else + +/* Libcrypto specific stuff */ + +void **libcrypto_mutexes; + +static void libcrypto_lock_callback(int mode, int i, const char *file, int line){ + (void)file; + (void)line; + if(mode & CRYPTO_LOCK){ + user_callbacks->mutex_lock(&libcrypto_mutexes[i]); + } else { + user_callbacks->mutex_unlock(&libcrypto_mutexes[i]); + } +} + +static int libcrypto_thread_init(){ + int n=CRYPTO_num_locks(); + int i; + libcrypto_mutexes=malloc(sizeof(void *) * n); + if (libcrypto_mutexes == NULL) + return SSH_ERROR; + for (i=0;imutex_init(&libcrypto_mutexes[i]); + } + CRYPTO_set_id_callback(user_callbacks->thread_id); + CRYPTO_set_locking_callback(libcrypto_lock_callback); + + return SSH_OK; +} + +static void libcrypto_thread_finalize(){ + int n=CRYPTO_num_locks(); + int i; + if (libcrypto_mutexes==NULL) + return; + for (i=0;imutex_destroy(&libcrypto_mutexes[i]); + } + SAFE_FREE(libcrypto_mutexes); + +} + +#endif + +/** @internal + * @brief inits the threading with the backend cryptographic libraries + */ + +int ssh_threads_init(void){ + static int threads_initialized=0; + int ret; + if(threads_initialized) + return SSH_OK; + /* first initialize the user_callbacks with our default handlers if not + * already the case + */ + if(user_callbacks == NULL){ +#ifdef HAVE_PTHREAD + user_callbacks=&ssh_pthread_user_callbacks; + } +#else + return SSH_ERROR; // Can't do anything to initialize threading + } +#endif + + /* Then initialize the crypto libraries threading callbacks */ +#ifdef HAVE_LIBGCRYPT + ret = libgcrypt_thread_init(); +#else /* Libcrypto */ + ret = libcrypto_thread_init(); +#endif + if(ret == SSH_OK) + threads_initialized=1; + return ret; +} + +void ssh_threads_finalize(void){ +#ifdef HAVE_LIBGCRYPT +#else + libcrypto_thread_finalize(); +#endif +} + +int ssh_threads_set_callbacks(struct ssh_threads_callbacks_struct *cb){ + user_callbacks=cb; + return SSH_OK; +} + +/** + * @} + */ -- cgit v1.2.3