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>
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user