diff options
-rw-r--r-- | include/libssh/callbacks.h | 71 | ||||
-rw-r--r-- | libssh/threads.c | 53 | ||||
-rw-r--r-- | tests/unittests/torture_rand.c | 5 |
3 files changed, 82 insertions, 47 deletions
diff --git a/include/libssh/callbacks.h b/include/libssh/callbacks.h index e66fb64e..f3e8f006 100644 --- a/include/libssh/callbacks.h +++ b/include/libssh/callbacks.h @@ -250,6 +250,10 @@ LIBSSH_API int ssh_set_callbacks(ssh_session session, ssh_callbacks cb); /** @} */ +/** @group libssh_threads + * @{ + */ + typedef int (*ssh_thread_callback) (void **lock); typedef unsigned long (*ssh_thread_id_callback) (void); struct ssh_threads_callbacks_struct { @@ -260,9 +264,74 @@ struct ssh_threads_callbacks_struct { ssh_thread_id_callback thread_id; }; -LIBSSH_API int ssh_init_set_threads_callbacks(struct ssh_threads_callbacks_struct +/** + * @brief sets the thread callbacks necessary if your program is using + * libssh in a multithreaded fashion. This function must be called first, + * outside of any threading context (in your main() for instance), before + * ssh_init(). + * @param cb pointer to a ssh_threads_callbacks_struct structure, which contains + * the different callbacks to be set. + * @see ssh_threads_callbacks_struct + * @see SSH_THREADS_PTHREAD + */ +LIBSSH_API int ssh_threads_set_callbacks(struct ssh_threads_callbacks_struct *cb); +/** @brief Defines the needed callbacks for pthread. Use this if your + * OS supports libpthread and want to use it for threading. + * @code + * #include <libssh/callbacks.h> + * #include <errno.h> + * #include <pthread.h> + * SSH_THREADS_PTHREAD(ssh_pthread_callbacks); + * int main(){ + * ssh_init_set_threads_callbacks(&ssh_pthread_callbacks); + * ssh_init(); + * ... + * } + * @endcode + * @param name name of the structure to be declared, containing the + * callbacks for threading + * + */ +#define SSH_THREADS_PTHREAD(name) \ +static int ssh_pthread_mutex_init (void **priv){ \ + int err = 0; \ + *priv = malloc (sizeof (pthread_mutex_t)); \ + if (*priv==NULL) \ + return ENOMEM; \ + err = pthread_mutex_init (*priv, NULL); \ + if (err != 0){ \ + free (*priv); \ + *priv=NULL; \ + } \ + return err; \ +} \ +static int ssh_pthread_mutex_destroy (void **lock) { \ + int err = pthread_mutex_destroy (*lock); \ + free (*lock); \ + *lock=NULL; \ + return err; \ +} \ +static int ssh_pthread_mutex_lock (void **lock) { \ + return pthread_mutex_lock (*lock); \ +} \ +static int ssh_pthread_mutex_unlock (void **lock){ \ + return pthread_mutex_unlock (*lock); \ +} \ +static unsigned long ssh_pthread_thread_id (void){ \ + return (unsigned long) pthread_self(); \ +} \ +static struct ssh_threads_callbacks_struct name= \ +{ \ + .mutex_init=ssh_pthread_mutex_init, \ + .mutex_destroy=ssh_pthread_mutex_destroy, \ + .mutex_lock=ssh_pthread_mutex_lock, \ + .mutex_unlock=ssh_pthread_mutex_unlock, \ + .thread_id=ssh_pthread_thread_id \ +} + +/** @} */ #ifdef __cplusplus } #endif diff --git a/libssh/threads.c b/libssh/threads.c index 76853f26..7cac6dbf 100644 --- a/libssh/threads.c +++ b/libssh/threads.c @@ -37,52 +37,12 @@ #warning "application doesn't provide the threading callbacks, you're screwed" #endif + #ifdef HAVE_PTHREAD + #include <errno.h> #include <pthread.h> - -static int ssh_pthread_mutex_init (void **priv){ - int err = 0; - *priv = malloc (sizeof (pthread_mutex_t)); - - if (*priv==NULL) - return ENOMEM; - err = pthread_mutex_init (*priv, NULL); - if (err != 0){ - free (*priv); - *priv=NULL; - } - return err; -} - -static int ssh_pthread_mutex_destroy (void **lock) { - int err = pthread_mutex_destroy (*lock); - free (*lock); - *lock=NULL; - return err; -} - -static int ssh_pthread_mutex_lock (void **lock) { - return pthread_mutex_lock (*lock); -} - -static int ssh_pthread_mutex_unlock (void **lock){ - return pthread_mutex_unlock (*lock); -} - -static unsigned long ssh_pthread_thread_id (void){ - return (unsigned long) pthread_self(); -} - -static struct ssh_threads_callbacks_struct ssh_pthread_user_callbacks= -{ - .mutex_init=ssh_pthread_mutex_init, - .mutex_destroy=ssh_pthread_mutex_destroy, - .mutex_lock=ssh_pthread_mutex_lock, - .mutex_unlock=ssh_pthread_mutex_unlock, - .thread_id=ssh_pthread_thread_id -}; - +SSH_THREADS_PTHREAD(ssh_pthread_user_callbacks); #endif /* HAVE_PTHREAD */ #endif /* _WIN32 */ @@ -165,10 +125,11 @@ int ssh_threads_init(void){ if(user_callbacks == NULL){ #ifdef HAVE_PTHREAD user_callbacks=&ssh_pthread_user_callbacks; - } else { -#endif + } +#else return SSH_ERROR; // Can't do anything to initialize threading } +#endif /* Then initialize the crypto libraries threading callbacks */ #ifdef HAVE_LIBGCRYPT @@ -188,7 +149,7 @@ void ssh_threads_finalize(void){ #endif } -int ssh_init_set_threads_callbacks(struct ssh_threads_callbacks_struct *cb){ +int ssh_threads_set_callbacks(struct ssh_threads_callbacks_struct *cb){ user_callbacks=cb; return SSH_OK; } diff --git a/tests/unittests/torture_rand.c b/tests/unittests/torture_rand.c index d5a1b5c5..87ecd9a6 100644 --- a/tests/unittests/torture_rand.c +++ b/tests/unittests/torture_rand.c @@ -1,6 +1,8 @@ #define LIBSSH_STATIC #include <libssh/priv.h> +#include <libssh/callbacks.h> #include <pthread.h> +#include <errno.h> #include "torture.h" #ifdef HAVE_LIBGCRYPT @@ -10,8 +12,11 @@ #define NUM_LOOPS 20000 #endif #define NUM_THREADS 100 +SSH_THREADS_PTHREAD(ssh_pthread_callbacks); static void setup(){ + printf("setup\n"); + ssh_threads_set_callbacks(&ssh_pthread_callbacks); ssh_init(); } |