diff options
author | Matt Caswell <matt@openssl.org> | 2015-11-13 23:54:44 +0000 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2015-11-20 23:39:30 +0000 |
commit | 68487a9b0631d27be9a1f4565e7e652ae9cb6aad (patch) | |
tree | f08b9aedfa12d06d5602f2422def273b96f7ea2c /crypto | |
parent | 27949c353e68825f119410f8fd73ae1d667581c7 (diff) | |
download | openssl-68487a9b0631d27be9a1f4565e7e652ae9cb6aad.tar.gz |
Convert __thread to pthreads for Thread Local Storage
In theory the pthreads approach for Thread Local Storage should be more
portable.
This also changes some APIs in order to accommodate this change. In
particular ASYNC_init_pool is renamed ASYNC_init_thread and
ASYNC_free_pool is renamed ASYNC_cleanup_thread. Also introduced ASYNC_init
and ASYNC_cleanup.
Reviewed-by: Rich Salz <rsalz@openssl.org>
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/async/arch/async_null.c | 10 | ||||
-rw-r--r-- | crypto/async/arch/async_posix.c | 13 | ||||
-rw-r--r-- | crypto/async/arch/async_posix.h | 16 | ||||
-rw-r--r-- | crypto/async/async.c | 44 | ||||
-rw-r--r-- | crypto/async/async_err.c | 2 | ||||
-rw-r--r-- | crypto/async/async_locl.h | 1 |
6 files changed, 62 insertions, 24 deletions
diff --git a/crypto/async/arch/async_null.c b/crypto/async/arch/async_null.c index 8de50ed531..dba159f309 100644 --- a/crypto/async/arch/async_null.c +++ b/crypto/async/arch/async_null.c @@ -61,6 +61,11 @@ int async_pipe(OSSL_ASYNC_FD *pipefds) return -1; } +int async_close_fd(OSSL_ASYNC_FD fd) +{ + return 0; +} + int async_write1(OSSL_ASYNC_FD fd, const void *buf) { return -1; @@ -71,5 +76,10 @@ int async_read1(OSSL_ASYNC_FD fd, void *buf) return -1; } +int async_thread_local_init(void) +{ + return 0; +} + #endif diff --git a/crypto/async/arch/async_posix.c b/crypto/async/arch/async_posix.c index 541c8b36b4..bd4b0c2f1b 100644 --- a/crypto/async/arch/async_posix.c +++ b/crypto/async/arch/async_posix.c @@ -61,11 +61,20 @@ # include <openssl/crypto.h> # include <openssl/async.h> -__thread async_ctx *posixctx; -__thread async_pool *posixpool; +pthread_key_t posixctx; +pthread_key_t posixpool; #define STACKSIZE 32768 +int async_thread_local_init(void) +{ + if (pthread_key_create(&posixctx, NULL) != 0 + || pthread_key_create(&posixpool, NULL) != 0) + return 0; + + return 1; +} + int async_fibre_init(async_fibre *fibre) { void *stack = NULL; diff --git a/crypto/async/arch/async_posix.h b/crypto/async/arch/async_posix.h index 9fdccf9e76..36fae24788 100644 --- a/crypto/async/arch/async_posix.h +++ b/crypto/async/arch/async_posix.h @@ -52,12 +52,14 @@ */ #include <openssl/e_os2.h> -#ifdef OPENSSL_SYS_UNIX +#if defined(OPENSSL_SYS_UNIX) && defined(OPENSSL_THREADS) # include <unistd.h> # if _POSIX_VERSION >= 200112L +# include <pthread.h> + # define ASYNC_POSIX # define ASYNC_ARCH @@ -73,8 +75,8 @@ # include <setjmp.h> # include "e_os.h" -extern __thread async_ctx *posixctx; -extern __thread async_pool *posixpool; +extern pthread_key_t posixctx; +extern pthread_key_t posixpool; typedef struct async_fibre_st { ucontext_t fibre; @@ -82,10 +84,10 @@ typedef struct async_fibre_st { int env_init; } async_fibre; -# define async_set_ctx(nctx) (posixctx = (nctx)) -# define async_get_ctx() (posixctx) -# define async_set_pool(p) (posixpool = (p)) -# define async_get_pool() (posixpool) +# define async_set_ctx(nctx) (pthread_setspecific(posixctx , (nctx)) == 0) +# define async_get_ctx() ((async_ctx *)pthread_getspecific(posixctx)) +# define async_set_pool(p) (pthread_setspecific(posixpool , (p)) == 0) +# define async_get_pool() ((async_pool *)pthread_getspecific(posixpool)) static inline int async_fibre_swapcontext(async_fibre *o, async_fibre *n, int r) { diff --git a/crypto/async/async.c b/crypto/async/async.c index 4a89499c7b..c18c5c4517 100644 --- a/crypto/async/async.c +++ b/crypto/async/async.c @@ -156,7 +156,7 @@ static ASYNC_JOB *async_get_pool_job(void) { * Pool has not been initialised, so init with the defaults, i.e. * no max size and no pre-created jobs */ - if (ASYNC_init_pool(0, 0) == 0) + if (ASYNC_init_thread(0, 0) == 0) return NULL; pool = async_get_pool(); } @@ -328,30 +328,36 @@ static void async_empty_pool(async_pool *pool) } while (job); } -int ASYNC_init_pool(size_t max_size, size_t init_size) +int ASYNC_init(int init_thread, size_t max_size, size_t init_size) +{ + if (!async_thread_local_init()) + return 0; + + if (init_thread) + return ASYNC_init_thread(max_size, init_size); + + return 1; +} + +int ASYNC_init_thread(size_t max_size, size_t init_size) { async_pool *pool; size_t curr_size = 0; - if (init_size > max_size || max_size == 0) { - ASYNCerr(ASYNC_F_ASYNC_INIT_POOL, ASYNC_R_INVALID_POOL_SIZE); - return 0; - } - - if(async_get_pool() != NULL) { - ASYNCerr(ASYNC_F_ASYNC_INIT_POOL, ASYNC_R_POOL_ALREADY_INITED); + if (init_size > max_size) { + ASYNCerr(ASYNC_F_ASYNC_INIT_THREAD, ASYNC_R_INVALID_POOL_SIZE); return 0; } pool = OPENSSL_zalloc(sizeof *pool); if (pool == NULL) { - ASYNCerr(ASYNC_F_ASYNC_INIT_POOL, ERR_R_MALLOC_FAILURE); + ASYNCerr(ASYNC_F_ASYNC_INIT_THREAD, ERR_R_MALLOC_FAILURE); return 0; } pool->jobs = sk_ASYNC_JOB_new_null(); if (pool->jobs == NULL) { - ASYNCerr(ASYNC_F_ASYNC_INIT_POOL, ERR_R_MALLOC_FAILURE); + ASYNCerr(ASYNC_F_ASYNC_INIT_THREAD, ERR_R_MALLOC_FAILURE); OPENSSL_free(pool); return 0; } @@ -379,7 +385,7 @@ int ASYNC_init_pool(size_t max_size, size_t init_size) pool->curr_size = curr_size; if (!async_set_pool(pool)) { - ASYNCerr(ASYNC_F_ASYNC_INIT_POOL, ASYNC_R_FAILED_TO_SET_POOL); + ASYNCerr(ASYNC_F_ASYNC_INIT_THREAD, ASYNC_R_FAILED_TO_SET_POOL); goto err; } @@ -397,15 +403,25 @@ static void async_free_pool_internal(async_pool *pool) async_empty_pool(pool); sk_ASYNC_JOB_free(pool->jobs); OPENSSL_free(pool); - async_set_pool(NULL); + (void)async_set_pool(NULL); async_ctx_free(); } -void ASYNC_free_pool(void) +void ASYNC_cleanup_thread(void) { async_free_pool_internal(async_get_pool()); } +void ASYNC_cleanup(int cleanupthread) +{ + /* + * We don't actually have any global cleanup at the moment so just cleanup + * the thread + */ + if (cleanupthread) + ASYNC_cleanup_thread(); +} + ASYNC_JOB *ASYNC_get_current_job(void) { async_ctx *ctx; diff --git a/crypto/async/async_err.c b/crypto/async/async_err.c index d4bdbc7815..07a169ba86 100644 --- a/crypto/async/async_err.c +++ b/crypto/async/async_err.c @@ -71,7 +71,7 @@ static ERR_STRING_DATA ASYNC_str_functs[] = { {ERR_FUNC(ASYNC_F_ASYNC_CTX_NEW), "async_ctx_new"}, - {ERR_FUNC(ASYNC_F_ASYNC_INIT_POOL), "ASYNC_init_pool"}, + {ERR_FUNC(ASYNC_F_ASYNC_INIT_THREAD), "ASYNC_init_thread"}, {ERR_FUNC(ASYNC_F_ASYNC_JOB_NEW), "async_job_new"}, {ERR_FUNC(ASYNC_F_ASYNC_PAUSE_JOB), "ASYNC_pause_job"}, {ERR_FUNC(ASYNC_F_ASYNC_START_FUNC), "async_start_func"}, diff --git a/crypto/async/async_locl.h b/crypto/async/async_locl.h index 1a98f36b79..0a9c59fcfb 100644 --- a/crypto/async/async_locl.h +++ b/crypto/async/async_locl.h @@ -86,6 +86,7 @@ struct async_pool_st { size_t max_size; }; +int async_thread_local_init(void); void async_start_func(void); int async_pipe(OSSL_ASYNC_FD *pipefds); int async_close_fd(OSSL_ASYNC_FD fd); |