#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;
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) {
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)
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;
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 {
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;