Convert ASYNC code to use new Thread API
authorMatt Caswell <matt@openssl.org>
Wed, 2 Mar 2016 16:15:52 +0000 (16:15 +0000)
committerMatt Caswell <matt@openssl.org>
Wed, 2 Mar 2016 17:23:42 +0000 (17:23 +0000)
The async code uses thread local variables. We should convert to using
the new Thread API for doing this.

Reviewed-by: Rich Salz <rsalz@openssl.org>
crypto/async/arch/async_null.c
crypto/async/arch/async_null.h
crypto/async/arch/async_posix.c
crypto/async/arch/async_posix.h
crypto/async/arch/async_win.c
crypto/async/arch/async_win.h
crypto/async/async.c
crypto/async/async_locl.h

index 03f8ebfa1074080a7f996f0bb7191ef92351204b..7b93090a9a87c13bb295a1a776108963a44effa9 100644 (file)
 
 #ifdef ASYNC_NULL
 
-int async_global_init(void)
-{
-    return 0;
-}
-
 void async_local_cleanup(void)
 {
 }
 
-void async_global_cleanup(void)
-{
-}
-
 #endif
 
index 4cd0a8b96638593b002ae66143263b19673e7632..a965bdbbd8494d57eb730d8032f70a4c21d58056 100644 (file)
@@ -65,13 +65,9 @@ typedef struct async_fibre_st {
 } async_fibre;
 
 
-# define async_set_ctx(nctx)                    0
-# define async_arch_get_ctx()                   ((async_ctx *)NULL)
 # define async_fibre_swapcontext(o,n,r)         0
 # define async_fibre_makecontext(c)             0
 # define async_fibre_free(f)
 # define async_fibre_init_dispatcher(f)
-# define async_get_pool()                       NULL
-# define async_set_pool(p)                      0
 
 #endif
index 626471d370c798193e16acdd90c81447b1593872..553ec664e2ce0762bafc8e8304e273829154d556 100644 (file)
 # include <stddef.h>
 # include <unistd.h>
 
-pthread_key_t posixctx;
-pthread_key_t posixpool;
-
 #define STACKSIZE       32768
 
-int async_global_init(void)
-{
-    if (pthread_key_create(&posixctx, NULL) != 0
-            || pthread_key_create(&posixpool, NULL) != 0)
-        return 0;
-
-    return 1;
-}
-
 void async_local_cleanup(void)
 {
 }
 
-void async_global_cleanup(void)
-{
-}
 
 int async_fibre_makecontext(async_fibre *fibre)
 {
index 7f1bdd1cc5f57350c13b5e3ff6137c6f45efabb9..de80f95f9d44fe5949e2d7b23bd7181252320f3e 100644 (file)
 #  include <setjmp.h>
 #  include "e_os.h"
 
-extern pthread_key_t posixctx;
-extern pthread_key_t posixpool;
-
 typedef struct async_fibre_st {
     ucontext_t fibre;
     jmp_buf env;
     int env_init;
 } async_fibre;
 
-#  define async_set_ctx(nctx)  (pthread_setspecific(posixctx , (nctx)) == 0)
-#  define async_arch_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)
 {
     o->env_init = 1;
index c0776b12394bca5db44af82465c09f5c8ca12080..6b948c3d9cf394c3b59e8587edb2218299d23547 100644 (file)
 # include <windows.h>
 # include "internal/cryptlib.h"
 
-struct winpool {
-    STACK_OF(ASYNC_JOB) *pool;
-    size_t curr_size;
-    size_t max_size;
-};
-
-static DWORD asyncwinpool = 0;
-static DWORD asyncwinctx = 0;
-
-
-void async_start_func(void);
-
-int async_global_init(void)
-{
-    asyncwinpool = TlsAlloc();
-    asyncwinctx = TlsAlloc();
-    if (asyncwinpool == TLS_OUT_OF_INDEXES
-            || asyncwinctx == TLS_OUT_OF_INDEXES) {
-        if (asyncwinpool != TLS_OUT_OF_INDEXES) {
-            TlsFree(asyncwinpool);
-        }
-        if (asyncwinctx != TLS_OUT_OF_INDEXES) {
-            TlsFree(asyncwinctx);
-        }
-        return 0;
-    }
-    return 1;
-}
-
 void async_local_cleanup(void)
 {
-    async_ctx *ctx = async_arch_get_ctx();
+    async_ctx *ctx = async_get_ctx();
     if (ctx != NULL) {
         async_fibre *fibre = &ctx->dispatcher;
         if(fibre != NULL && fibre->fibre != NULL && fibre->converted) {
@@ -99,14 +70,6 @@ void async_local_cleanup(void)
     }
 }
 
-void async_global_cleanup(void)
-{
-    TlsFree(asyncwinpool);
-    TlsFree(asyncwinctx);
-    asyncwinpool = 0;
-    asyncwinctx = 0;
-}
-
 int async_fibre_init_dispatcher(async_fibre *fibre)
 {
     fibre->fibre = ConvertThreadToFiber(NULL);
@@ -127,25 +90,4 @@ VOID CALLBACK async_start_func_win(PVOID unused)
     async_start_func();
 }
 
-async_pool *async_get_pool(void)
-{
-    return (async_pool *)TlsGetValue(asyncwinpool);
-}
-
-
-int async_set_pool(async_pool *pool)
-{
-    return TlsSetValue(asyncwinpool, (LPVOID)pool) != 0;
-}
-
-async_ctx *async_arch_get_ctx(void)
-{
-    return (async_ctx *)TlsGetValue(asyncwinctx);
-}
-
-int async_set_ctx(async_ctx *ctx)
-{
-    return TlsSetValue(asyncwinctx, (LPVOID)ctx) != 0;
-}
-
 #endif
index 87e30a4f6e98a656273407622562c252d6f4de87..42873307d08b32197b470e3a452a4ded95041da1 100644 (file)
@@ -73,13 +73,7 @@ typedef struct async_fibre_st {
         ((c)->fibre = CreateFiber(0, async_start_func_win, 0))
 # define async_fibre_free(f)             (DeleteFiber((f)->fibre))
 
-async_ctx *async_arch_get_ctx(void);
-int async_set_ctx(async_ctx *ctx);
-
 int async_fibre_init_dispatcher(async_fibre *fibre);
 VOID CALLBACK async_start_func_win(PVOID unused);
 
-async_pool *async_get_pool(void);
-int async_set_pool(async_pool *pool);
-
 #endif
index de2ec4a7c6f2a6312e574e9ffa45f4b2c88e6021..67e19c730f3bc7857fb8d3afe0ded962a4bc2a3e 100644 (file)
@@ -61,6 +61,7 @@
 /* This must be the first #include file */
 #include "async_locl.h"
 
+#include <internal/threads.h>
 #include <openssl/err.h>
 #include <internal/cryptlib_int.h>
 #include <string.h>
@@ -70,6 +71,9 @@
 #define ASYNC_JOB_PAUSED    2
 #define ASYNC_JOB_STOPPING  3
 
+static CRYPTO_THREAD_LOCAL ctxkey;
+static CRYPTO_THREAD_LOCAL poolkey;
+
 static void async_free_pool_internal(async_pool *pool);
 
 static async_ctx *async_ctx_new(void)
@@ -85,7 +89,7 @@ static async_ctx *async_ctx_new(void)
     async_fibre_init_dispatcher(&nctx->dispatcher);
     nctx->currjob = NULL;
     nctx->blocked = 0;
-    if (!async_set_ctx(nctx))
+    if (!CRYPTO_THREAD_set_local(&ctxkey, nctx))
         goto err;
 
     return nctx;
@@ -95,11 +99,12 @@ err:
     return NULL;
 }
 
-static async_ctx *async_get_ctx(void)
+async_ctx *async_get_ctx(void)
 {
     if (!OPENSSL_init_crypto(OPENSSL_INIT_ASYNC, NULL))
         return NULL;
-    return async_arch_get_ctx();
+
+    return (async_ctx *)CRYPTO_THREAD_get_local(&ctxkey);
 }
 
 static int async_ctx_free(void)
@@ -108,7 +113,7 @@ static int async_ctx_free(void)
 
     ctx = async_get_ctx();
 
-    if (!async_set_ctx(NULL))
+    if (!CRYPTO_THREAD_set_local(&ctxkey, NULL))
         return 0;
 
     OPENSSL_free(ctx);
@@ -144,7 +149,7 @@ static ASYNC_JOB *async_get_pool_job(void) {
     ASYNC_JOB *job;
     async_pool *pool;
 
-    pool = async_get_pool();
+    pool = (async_pool *)CRYPTO_THREAD_get_local(&poolkey);
     if (pool == NULL) {
         /*
          * Pool has not been initialised, so init with the defaults, i.e.
@@ -152,7 +157,7 @@ static ASYNC_JOB *async_get_pool_job(void) {
          */
         if (ASYNC_init_thread(0, 0) == 0)
             return NULL;
-        pool = async_get_pool();
+        pool = (async_pool *)CRYPTO_THREAD_get_local(&poolkey);
     }
 
     job = sk_ASYNC_JOB_pop(pool->jobs);
@@ -176,7 +181,7 @@ static ASYNC_JOB *async_get_pool_job(void) {
 static void async_release_job(ASYNC_JOB *job) {
     async_pool *pool;
 
-    pool = async_get_pool();
+    pool = (async_pool *)CRYPTO_THREAD_get_local(&poolkey);
     OPENSSL_free(job->funcargs);
     job->funcargs = NULL;
     sk_ASYNC_JOB_push(pool->jobs, job);
@@ -335,12 +340,25 @@ static void async_empty_pool(async_pool *pool)
 
 int async_init(void)
 {
-    if (!async_global_init())
+    if (!CRYPTO_THREAD_init_local(&ctxkey, NULL))
+        return 0;
+
+    if (!CRYPTO_THREAD_init_local(&poolkey, NULL)) {
+        CRYPTO_THREAD_cleanup_local(&ctxkey);
         return 0;
+    }
 
     return 1;
 }
 
+/* TODO: FIXME: This needs to be called by something!!! */
+void async_deinit(void);
+void async_deinit(void)
+{
+    CRYPTO_THREAD_cleanup_local(&ctxkey);
+    CRYPTO_THREAD_cleanup_local(&poolkey);
+}
+
 int ASYNC_init_thread(size_t max_size, size_t init_size)
 {
     async_pool *pool;
@@ -390,7 +408,7 @@ int ASYNC_init_thread(size_t max_size, size_t init_size)
         curr_size++;
     }
     pool->curr_size = curr_size;
-    if (!async_set_pool(pool)) {
+    if (!CRYPTO_THREAD_set_local(&poolkey, pool)) {
         ASYNCerr(ASYNC_F_ASYNC_INIT_THREAD, ASYNC_R_FAILED_TO_SET_POOL);
         goto err;
     }
@@ -409,14 +427,14 @@ static void async_free_pool_internal(async_pool *pool)
     async_empty_pool(pool);
     sk_ASYNC_JOB_free(pool->jobs);
     OPENSSL_free(pool);
-    (void)async_set_pool(NULL);
+    CRYPTO_THREAD_set_local(&poolkey, NULL);
     async_local_cleanup();
     async_ctx_free();
 }
 
 void ASYNC_cleanup_thread(void)
 {
-    async_free_pool_internal(async_get_pool());
+    async_free_pool_internal((async_pool *)CRYPTO_THREAD_get_local(&poolkey));
 }
 
 ASYNC_JOB *ASYNC_get_current_job(void)
index 4caf16db2c01fa5a691e44d450fbc280213838ec..7fa1f26c005c2795e53682578e63f6bd9de43c4a 100644 (file)
@@ -108,10 +108,9 @@ struct async_pool_st {
     size_t max_size;
 };
 
-int async_global_init(void);
 void async_local_cleanup(void);
-void async_global_cleanup(void);
 void async_start_func(void);
+async_ctx *async_get_ctx(void);
 
 void async_wait_ctx_reset_counts(ASYNC_WAIT_CTX *ctx);