int ASYNC_pause_job(void) { ASYNC_JOB *job; if (async_get_ctx() == NULL || async_get_ctx()->currjob == NULL || async_get_ctx()->blocked) { /* * Could be we've deliberately not been started within a job so this is * counted as success. */ return 1; } job = async_get_ctx()->currjob; job->status = ASYNC_JOB_PAUSING; if (!async_fibre_swapcontext(&job->fibrectx, &async_get_ctx()->dispatcher, 1)) { ASYNCerr(ASYNC_F_ASYNC_PAUSE_JOB, ASYNC_R_FAILED_TO_SWAP_CONTEXT); return 0; } return 1; }
void ASYNC_block_pause(void) { if (async_get_ctx() == NULL || async_get_ctx()->currjob == NULL) { /* * We're not in a job anyway so ignore this */ return; } async_get_ctx()->blocked++; }
int ASYNC_pause_job(void) { ASYNC_JOB *job; async_ctx *ctx = async_get_ctx(); if (ctx == NULL || ctx->currjob == NULL || ctx->blocked) { /* * Could be we've deliberately not been started within a job so this is * counted as success. */ return 1; } job = ctx->currjob; job->status = ASYNC_JOB_PAUSING; if (!async_fibre_swapcontext(&job->fibrectx, &ctx->dispatcher, 1)) { ASYNCerr(ASYNC_F_ASYNC_PAUSE_JOB, ASYNC_R_FAILED_TO_SWAP_CONTEXT); return 0; } /* Reset counts of added and deleted fds */ async_wait_ctx_reset_counts(job->waitctx); return 1; }
ASYNC_JOB *ASYNC_get_current_job(void) { async_ctx *ctx; ctx = async_get_ctx(); if (ctx == NULL) return NULL; return ctx->currjob; }
void ASYNC_block_pause(void) { async_ctx *ctx = async_get_ctx(); if (ctx == NULL || ctx->currjob == NULL) { /* * We're not in a job anyway so ignore this */ return; } ctx->blocked++; }
void async_local_cleanup(void) { async_ctx *ctx = async_get_ctx(); if (ctx != NULL) { async_fibre *fibre = &ctx->dispatcher; if(fibre != NULL && fibre->fibre != NULL && fibre->converted) { ConvertFiberToThread(); fibre->fibre = NULL; } } }
void async_start_func(void) { ASYNC_JOB *job; while (1) { /* Run the job */ job = async_get_ctx()->currjob; job->ret = job->func(job->funcargs); /* Stop the job */ job->status = ASYNC_JOB_STOPPING; if (!async_fibre_swapcontext(&job->fibrectx, &async_get_ctx()->dispatcher, 1)) { /* * Should not happen. Getting here will close the thread...can't do * much about it */ ASYNCerr(ASYNC_F_ASYNC_START_FUNC, ASYNC_R_FAILED_TO_SWAP_CONTEXT); } } }
static int async_ctx_free(void) { async_ctx *ctx; ctx = async_get_ctx(); if (!CRYPTO_THREAD_set_local(&ctxkey, NULL)) return 0; OPENSSL_free(ctx); return 1; }
static int async_ctx_free(void) { async_ctx *ctx; ctx = async_get_ctx(); if (!async_set_ctx(NULL)) return 0; OPENSSL_free(ctx); return 1; }
int ASYNC_start_job(ASYNC_JOB **job, ASYNC_WAIT_CTX *wctx, int *ret, int (*func)(void *), void *args, size_t size) { async_ctx *ctx = async_get_ctx(); if (ctx == NULL) ctx = async_ctx_new(); if (ctx == NULL) { return ASYNC_ERR; } if (*job) { ctx->currjob = *job; } for (;;) { if (ctx->currjob != NULL) { if (ctx->currjob->status == ASYNC_JOB_STOPPING) { *ret = ctx->currjob->ret; ctx->currjob->waitctx = NULL; async_release_job(ctx->currjob); ctx->currjob = NULL; *job = NULL; return ASYNC_FINISH; } if (ctx->currjob->status == ASYNC_JOB_PAUSING) { *job = ctx->currjob; ctx->currjob->status = ASYNC_JOB_PAUSED; ctx->currjob = NULL; return ASYNC_PAUSE; } if (ctx->currjob->status == ASYNC_JOB_PAUSED) { ctx->currjob = *job; /* Resume previous job */ if (!async_fibre_swapcontext(&ctx->dispatcher, &ctx->currjob->fibrectx, 1)) { ASYNCerr(ASYNC_F_ASYNC_START_JOB, ASYNC_R_FAILED_TO_SWAP_CONTEXT); goto err; } continue; } /* Should not happen */ ASYNCerr(ASYNC_F_ASYNC_START_JOB, ERR_R_INTERNAL_ERROR); async_release_job(ctx->currjob); ctx->currjob = NULL; *job = NULL; return ASYNC_ERR; } /* Start a new job */ if ((ctx->currjob = async_get_pool_job()) == NULL) { return ASYNC_NO_JOBS; } if (args != NULL) { ctx->currjob->funcargs = OPENSSL_malloc(size); if (ctx->currjob->funcargs == NULL) { ASYNCerr(ASYNC_F_ASYNC_START_JOB, ERR_R_MALLOC_FAILURE); async_release_job(ctx->currjob); ctx->currjob = NULL; return ASYNC_ERR; } memcpy(ctx->currjob->funcargs, args, size); } else { ctx->currjob->funcargs = NULL; } ctx->currjob->func = func; ctx->currjob->waitctx = wctx; if (!async_fibre_swapcontext(&ctx->dispatcher, &ctx->currjob->fibrectx, 1)) { ASYNCerr(ASYNC_F_ASYNC_START_JOB, ASYNC_R_FAILED_TO_SWAP_CONTEXT); goto err; } } err: async_release_job(ctx->currjob); ctx->currjob = NULL; *job = NULL; return ASYNC_ERR; }