aboutsummaryrefslogtreecommitdiff
path: root/crypto/async/async.c
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2015-11-13 15:21:20 +0000
committerMatt Caswell <matt@openssl.org>2015-11-20 23:37:17 +0000
commit27949c353e68825f119410f8fd73ae1d667581c7 (patch)
tree8047b155949437358c5baed4769487472b2e70c7 /crypto/async/async.c
parent2b2c78d4f0a73498739cfc0879299d7325c35160 (diff)
downloadopenssl-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.c72
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;