Simplify async pool handling
authorMatt Caswell <matt@openssl.org>
Fri, 13 Nov 2015 15:21:20 +0000 (15:21 +0000)
committerMatt Caswell <matt@openssl.org>
Fri, 20 Nov 2015 23:37:17 +0000 (23:37 +0000)
A lot of the pool handling code was in the arch specific files, but was
actually boiler plate and the same across the implementations. This commit
moves as much code as possible out of the arch specific files.

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_err.c
crypto/async/async_locl.h
include/openssl/async.h

index f015c90fb738746347cebc9f5e32fc99841af3fe..8de50ed5313088725b1a6af657323674bcab043d 100644 (file)
 
 #ifdef ASYNC_NULL
 
-STACK_OF(ASYNC_JOB) *async_get_pool(void)
-{
-    return NULL;
-}
-
-int async_set_pool(STACK_OF(ASYNC_JOB) *poolin, size_t curr_size,
-                   size_t max_size)
-{
-    return 0;
-}
-
-void async_increment_pool_size(void)
-{
-    return;
-}
-
-void async_release_job_to_pool(ASYNC_JOB *job)
-{
-    return;
-}
-
-size_t async_pool_max_size(void)
-{
-    return 0;
-}
-
-void async_release_pool(void)
-{
-    return;
-}
-
-int async_pool_can_grow(void) {
-    return 0;
-}
-
 int async_pipe(OSSL_ASYNC_FD *pipefds)
 {
     return -1;
index e9344f5874aaa57e921e313fdf0117826c9341be..684e373b48f033c548ada44bfc0338186cca19bb 100644 (file)
@@ -72,5 +72,7 @@ typedef struct async_fibre_st {
 # define async_fibre_makecontext(c)
 # define async_fibre_free(f)
 # define async_fibre_init_dispatcher(f)
+# define async_get_pool()                       NULL
+# define async_set_pool(p)                      0
 
 #endif
index 3f6cb6274aa19bc403f8542d10a8b30eca7b5bc4..541c8b36b428d9bea7e0caaad1931844e24a6caf 100644 (file)
 # include <openssl/crypto.h>
 # include <openssl/async.h>
 
-__thread async_ctx *sysvctx;
+__thread async_ctx *posixctx;
+__thread async_pool *posixpool;
 
 #define STACKSIZE       32768
 
-extern __thread size_t posixpool_max_size;
-extern __thread size_t posixpool_curr_size;
-extern __thread STACK_OF(ASYNC_JOB) *posixpool;
-__thread size_t posixpool_max_size = 0;
-__thread size_t posixpool_curr_size = 0;
-__thread STACK_OF(ASYNC_JOB) *posixpool = NULL;
-
 int async_fibre_init(async_fibre *fibre)
 {
     void *stack = NULL;
@@ -103,6 +97,14 @@ int async_pipe(OSSL_ASYNC_FD *pipefds)
     return 0;
 }
 
+int async_close_fd(OSSL_ASYNC_FD fd)
+{
+    if (close(fd) != 0)
+        return 0;
+
+    return 1;
+}
+
 int async_write1(OSSL_ASYNC_FD fd, const void *buf)
 {
     if (write(fd, buf, 1) > 0)
@@ -119,45 +121,4 @@ int async_read1(OSSL_ASYNC_FD fd, void *buf)
     return 0;
 }
 
-STACK_OF(ASYNC_JOB) *async_get_pool(void)
-{
-    return posixpool;
-}
-
-int async_set_pool(STACK_OF(ASYNC_JOB) *poolin, size_t curr_size,
-                    size_t max_size)
-{
-    posixpool = poolin;
-    posixpool_curr_size = curr_size;
-    posixpool_max_size = max_size;
-    return 1;
-}
-
-void async_increment_pool_size(void)
-{
-    posixpool_curr_size++;
-}
-
-void async_release_job_to_pool(ASYNC_JOB *job)
-{
-    sk_ASYNC_JOB_push(posixpool, job);
-}
-
-size_t async_pool_max_size(void)
-{
-    return posixpool_max_size;
-}
-
-void async_release_pool(void)
-{
-    sk_ASYNC_JOB_free(posixpool);
-    posixpool = NULL;
-}
-
-int async_pool_can_grow(void)
-{
-    return (posixpool_max_size == 0)
-        || (posixpool_curr_size < posixpool_max_size);
-}
-
 #endif
index d5b23997adc586d7187ebd735be3eb841fe42497..9fdccf9e760998b842858f73e3c0c8d83226ca8a 100644 (file)
@@ -73,7 +73,8 @@
 #  include <setjmp.h>
 #  include "e_os.h"
 
-extern __thread async_ctx *sysvctx;
+extern __thread async_ctx *posixctx;
+extern __thread async_pool *posixpool;
 
 typedef struct async_fibre_st {
     ucontext_t fibre;
@@ -81,8 +82,10 @@ typedef struct async_fibre_st {
     int env_init;
 } async_fibre;
 
-#  define async_set_ctx(nctx)             (sysvctx = (nctx))
-#  define async_get_ctx()                 (sysvctx)
+#  define async_set_ctx(nctx)             (posixctx = (nctx))
+#  define async_get_ctx()                 (posixctx)
+#  define async_set_pool(p)               (posixpool = (p))
+#  define async_get_pool()                (posixpool)
 
 static inline int async_fibre_swapcontext(async_fibre *o, async_fibre *n, int r)
 {
index 9841a9ca929aa8317f77bfd7c19559407cb07602..4eb449d34f4f00967370f307566c31846939a464 100644 (file)
@@ -51,7 +51,7 @@
  * ====================================================================
  */
 
-#include "async_win.h"
+#include "../async_locl.h"
 
 #ifdef ASYNC_WIN
 
@@ -95,6 +95,14 @@ int async_pipe(OSSL_ASYNC_FD *pipefds)
     return 1;
 }
 
+int async_close_fd(OSSL_ASYNC_FD fd)
+{
+    if (CloseHandle(fd) == 0)
+        return 0;
+
+    return 1;
+}
+
 int async_write1(OSSL_ASYNC_FD fd, const void *buf)
 {
     DWORD numwritten = 0;
@@ -115,70 +123,17 @@ int async_read1(OSSL_ASYNC_FD fd, void *buf)
     return 0;
 }
 
-STACK_OF(ASYNC_JOB) *async_get_pool(void)
+async_pool *async_get_pool(void)
 {
-    struct winpool *pool;
-    pool = (struct winpool *)
+    return (async_pool *)
             CRYPTO_get_thread_local(CRYPTO_THREAD_LOCAL_ASYNC_POOL);
-    return pool->pool;
 }
 
 
-int async_set_pool(STACK_OF(ASYNC_JOB) *poolin, size_t curr_size,
-                    size_t max_size)
+int async_set_pool(async_pool *pool)
 {
-    struct winpool *pool;
-    pool = OPENSSL_malloc(sizeof *pool);
-    if (pool == NULL)
-        return 0;
-
-    pool->pool = poolin;
-    pool->curr_size = curr_size;
-    pool->max_size = max_size;
     CRYPTO_set_thread_local(CRYPTO_THREAD_LOCAL_ASYNC_POOL, (void *)pool);
     return 1;
 }
 
-void async_increment_pool_size(void)
-{
-    struct winpool *pool;
-    pool = (struct winpool *)
-            CRYPTO_get_thread_local(CRYPTO_THREAD_LOCAL_ASYNC_POOL);
-    pool->curr_size++;
-}
-
-void async_release_job_to_pool(ASYNC_JOB *job)
-{
-    struct winpool *pool;
-    pool = (struct winpool *)
-            CRYPTO_get_thread_local(CRYPTO_THREAD_LOCAL_ASYNC_POOL);
-    sk_ASYNC_JOB_push(pool->pool, job);
-}
-
-size_t async_pool_max_size(void)
-{
-    struct winpool *pool;
-    pool = (struct winpool *)
-            CRYPTO_get_thread_local(CRYPTO_THREAD_LOCAL_ASYNC_POOL);
-    return pool->max_size;
-}
-
-void async_release_pool(void)
-{
-    struct winpool *pool;
-    pool = (struct winpool *)
-            CRYPTO_get_thread_local(CRYPTO_THREAD_LOCAL_ASYNC_POOL);
-    sk_ASYNC_JOB_free(pool->pool);
-    OPENSSL_free(pool);
-    CRYPTO_set_thread_local(CRYPTO_THREAD_LOCAL_ASYNC_POOL, NULL);
-}
-
-int async_pool_can_grow(void)
-{
-    struct winpool *pool;
-    pool = (struct winpool *)
-            CRYPTO_get_thread_local(CRYPTO_THREAD_LOCAL_ASYNC_POOL);
-    return (pool->max_size == 0) || (pool->curr_size < pool->max_size);
-}
-
 #endif
index 42574a77bbc01f3306414c8a0480780e971064dc..5e91732e8722fef34b3003e699257a7754527083 100644 (file)
@@ -81,4 +81,7 @@ typedef struct async_fibre_st {
 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 5bf64afa226cb84803e8c9d9b94ff2ed1d5c4e4c..4a89499c7b07243c75ef933a22f6313b8ae554ec 100644 (file)
@@ -69,6 +69,8 @@
 #define ASYNC_JOB_PAUSED    2
 #define ASYNC_JOB_STOPPING  3
 
+static void async_free_pool_internal(async_pool *pool);
+
 static async_ctx *async_ctx_new(void)
 {
     async_ctx *nctx = NULL;
@@ -138,13 +140,15 @@ static void async_job_free(ASYNC_JOB *job)
     if (job != NULL) {
         OPENSSL_free(job->funcargs);
         async_fibre_free(&job->fibrectx);
+        async_close_fd(job->wait_fd);
+        async_close_fd(job->wake_fd);
         OPENSSL_free(job);
     }
 }
 
 static ASYNC_JOB *async_get_pool_job(void) {
     ASYNC_JOB *job;
-    STACK_OF(ASYNC_JOB) *pool;
+    async_pool *pool;
 
     pool = async_get_pool();
     if (pool == NULL) {
@@ -157,26 +161,28 @@ static ASYNC_JOB *async_get_pool_job(void) {
         pool = async_get_pool();
     }
 
-    job = sk_ASYNC_JOB_pop(pool);
+    job = sk_ASYNC_JOB_pop(pool->jobs);
     if (job == NULL) {
         /* Pool is empty */
-        if (!async_pool_can_grow())
+        if ((pool->max_size != 0) && (pool->curr_size >= pool->max_size))
             return NULL;
 
         job = async_job_new();
         if (job) {
             async_fibre_makecontext(&job->fibrectx);
-            async_increment_pool_size();
+            pool->curr_size++;
         }
     }
     return job;
 }
 
 static void async_release_job(ASYNC_JOB *job) {
+    async_pool *pool;
+
+    pool = async_get_pool();
     OPENSSL_free(job->funcargs);
     job->funcargs = NULL;
-    /* Ignore error return */
-    async_release_job_to_pool(job);
+    sk_ASYNC_JOB_push(pool->jobs, job);
 }
 
 void async_start_func(void)
@@ -309,31 +315,49 @@ int ASYNC_pause_job(void)
     return 1;
 }
 
-static void async_empty_pool(STACK_OF(ASYNC_JOB) *pool)
+static void async_empty_pool(async_pool *pool)
 {
     ASYNC_JOB *job;
 
+    if (!pool || !pool->jobs)
+        return;
+
     do {
-        job = sk_ASYNC_JOB_pop(pool);
+        job = sk_ASYNC_JOB_pop(pool->jobs);
         async_job_free(job);
     } while (job);
 }
 
 int ASYNC_init_pool(size_t max_size, size_t init_size)
 {
-    STACK_OF(ASYNC_JOB) *pool;
+    async_pool *pool;
     size_t curr_size = 0;
 
-    if (init_size > max_size) {
+    if (init_size > max_size || max_size == 0) {
         ASYNCerr(ASYNC_F_ASYNC_INIT_POOL, ASYNC_R_INVALID_POOL_SIZE);
         return 0;
     }
 
-    pool = sk_ASYNC_JOB_new_null();
+    if(async_get_pool() != NULL) {
+        ASYNCerr(ASYNC_F_ASYNC_INIT_POOL, ASYNC_R_POOL_ALREADY_INITED);
+        return 0;
+    }
+
+    pool = OPENSSL_zalloc(sizeof *pool);
     if (pool == NULL) {
         ASYNCerr(ASYNC_F_ASYNC_INIT_POOL, 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);
+        OPENSSL_free(pool);
+        return 0;
+    }
+
+    pool->max_size = max_size;
+
     /* Pre-create jobs as required */
     while (init_size) {
         ASYNC_JOB *job;
@@ -341,7 +365,7 @@ int ASYNC_init_pool(size_t max_size, size_t init_size)
         if (job) {
             async_fibre_makecontext(&job->fibrectx);
             job->funcargs = NULL;
-            sk_ASYNC_JOB_push(pool, job);
+            sk_ASYNC_JOB_push(pool->jobs, job);
             curr_size++;
             init_size--;
         } else {
@@ -352,30 +376,36 @@ int ASYNC_init_pool(size_t max_size, size_t init_size)
             init_size = 0;
         }
     }
+    pool->curr_size = curr_size;
 
-    if (!async_set_pool(pool, curr_size, max_size)) {
+    if (!async_set_pool(pool)) {
         ASYNCerr(ASYNC_F_ASYNC_INIT_POOL, ASYNC_R_FAILED_TO_SET_POOL);
-        async_empty_pool(pool);
-        sk_ASYNC_JOB_free(pool);
-        return 0;
+        goto err;
     }
 
     return 1;
+err:
+    async_free_pool_internal(pool);
+    return 0;
 }
 
-void ASYNC_free_pool(void)
+static void async_free_pool_internal(async_pool *pool)
 {
-    STACK_OF(ASYNC_JOB) *pool;
-
-    pool = async_get_pool();
     if (pool == NULL)
         return;
 
     async_empty_pool(pool);
-    async_release_pool();
+    sk_ASYNC_JOB_free(pool->jobs);
+    OPENSSL_free(pool);
+    async_set_pool(NULL);
     async_ctx_free();
 }
 
+void ASYNC_free_pool(void)
+{
+    async_free_pool_internal(async_get_pool());
+}
+
 ASYNC_JOB *ASYNC_get_current_job(void)
 {
     async_ctx *ctx;
index 1391c0f3d51172ccb48a8d0e6f9c4b75eadea466..d4bdbc78151bd2bfe53a1daffdbd2f8e80e8c254 100644 (file)
 # define ERR_REASON(reason) ERR_PACK(ERR_LIB_ASYNC,0,reason)
 
 static ERR_STRING_DATA ASYNC_str_functs[] = {
-    {ERR_FUNC(ASYNC_F_ASYNC_CTX_NEW), "ASYNC_CTX_NEW"},
+    {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_JOB_NEW), "ASYNC_JOB_NEW"},
+    {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"},
+    {ERR_FUNC(ASYNC_F_ASYNC_START_FUNC), "async_start_func"},
     {ERR_FUNC(ASYNC_F_ASYNC_START_JOB), "ASYNC_start_job"},
     {0, NULL}
 };
@@ -84,6 +84,7 @@ static ERR_STRING_DATA ASYNC_str_reasons[] = {
     {ERR_REASON(ASYNC_R_FAILED_TO_SET_POOL), "failed to set pool"},
     {ERR_REASON(ASYNC_R_FAILED_TO_SWAP_CONTEXT), "failed to swap context"},
     {ERR_REASON(ASYNC_R_INVALID_POOL_SIZE), "invalid pool size"},
+    {ERR_REASON(ASYNC_R_POOL_ALREADY_INITED), "pool already inited"},
     {0, NULL}
 };
 
index 3cf97479edaaa9a4c0b3d3ffbd12223d8fcc6424..1a98f36b79ffa2ed2cd5443d9f8775fb543f7c34 100644 (file)
@@ -55,6 +55,7 @@
 #include <openssl/crypto.h>
 
 typedef struct async_ctx_st async_ctx;
+typedef struct async_pool_st async_pool;
 
 #include "arch/async_win.h"
 #include "arch/async_posix.h"
@@ -79,15 +80,14 @@ struct async_job_st {
 
 DECLARE_STACK_OF(ASYNC_JOB)
 
+struct async_pool_st {
+    STACK_OF(ASYNC_JOB) *jobs;
+    size_t curr_size;
+    size_t max_size;
+};
+
 void async_start_func(void);
-STACK_OF(ASYNC_JOB) *async_get_pool(void);
-int async_set_pool(STACK_OF(ASYNC_JOB) *poolin, size_t curr_size,
-                   size_t max_size);
-void async_increment_pool_size(void);
-void async_release_job_to_pool(ASYNC_JOB *job);
-size_t async_pool_max_size(void);
-void async_release_pool(void);
-int async_pool_can_grow(void);
 int async_pipe(OSSL_ASYNC_FD *pipefds);
+int async_close_fd(OSSL_ASYNC_FD fd);
 int async_write1(OSSL_ASYNC_FD fd, const void *buf);
 int async_read1(OSSL_ASYNC_FD fd, void *buf);
index 0cfd7dc6830f07b66d401fa075c57bd8707f0388..acc86bceafbfeb3fef8e9db029055878a580064c 100644 (file)
@@ -111,6 +111,7 @@ void ERR_load_ASYNC_strings(void);
 # define ASYNC_R_FAILED_TO_SET_POOL                       101
 # define ASYNC_R_FAILED_TO_SWAP_CONTEXT                   102
 # define ASYNC_R_INVALID_POOL_SIZE                        103
+# define ASYNC_R_POOL_ALREADY_INITED                      104
 
 #ifdef  __cplusplus
 }