diff options
author | Matt Caswell <matt@openssl.org> | 2015-11-13 15:21:20 +0000 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2015-11-20 23:37:17 +0000 |
commit | 27949c353e68825f119410f8fd73ae1d667581c7 (patch) | |
tree | 8047b155949437358c5baed4769487472b2e70c7 /crypto/async/async.c | |
parent | 2b2c78d4f0a73498739cfc0879299d7325c35160 (diff) | |
download | openssl-27949c353e68825f119410f8fd73ae1d667581c7.zip openssl-27949c353e68825f119410f8fd73ae1d667581c7.tar.gz openssl-27949c353e68825f119410f8fd73ae1d667581c7.tar.bz2 |
Simplify async pool handling
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>
Diffstat (limited to 'crypto/async/async.c')
-rw-r--r-- | crypto/async/async.c | 72 |
1 files changed, 51 insertions, 21 deletions
diff --git a/crypto/async/async.c b/crypto/async/async.c index 5bf64af..4a89499 100644 --- a/crypto/async/async.c +++ b/crypto/async/async.c @@ -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; |