int ASYNC_start_job(ASYNC_JOB **job, int *ret, int (*func)(void *),
                         void *args, size_t size)
{
    if (async_get_ctx() == NULL && async_ctx_new() == NULL) {
        return ASYNC_ERR;
    }
    if (*job) {
        async_get_ctx()->currjob = *job;
    }
    for (;;) {
        if (async_get_ctx()->currjob != NULL) {
            if (async_get_ctx()->currjob->status == ASYNC_JOB_STOPPING) {
                *ret = async_get_ctx()->currjob->ret;
                async_release_job(async_get_ctx()->currjob);
                async_get_ctx()->currjob = NULL;
                *job = NULL;
                return ASYNC_FINISH;
            }
            if (async_get_ctx()->currjob->status == ASYNC_JOB_PAUSING) {
                *job = async_get_ctx()->currjob;
                async_get_ctx()->currjob->status = ASYNC_JOB_PAUSED;
                async_get_ctx()->currjob = NULL;
                return ASYNC_PAUSE;
            }
            if (async_get_ctx()->currjob->status == ASYNC_JOB_PAUSED) {
                async_get_ctx()->currjob = *job;
                if (!async_fibre_swapcontext(&async_get_ctx()->dispatcher,
                        &async_get_ctx()->currjob->fibrectx, 1)) {
                    ASYNCerr(ASYNC_F_ASYNC_START_JOB,
                             ASYNC_R_FAILED_TO_SWAP_CONTEXT);
                    goto err;
                }
                continue;
            }
            ASYNCerr(ASYNC_F_ASYNC_START_JOB, ERR_R_INTERNAL_ERROR);
            async_release_job(async_get_ctx()->currjob);
            async_get_ctx()->currjob = NULL;
            *job = NULL;
            return ASYNC_ERR;
        }
        if ((async_get_ctx()->currjob = async_get_pool_job()) == NULL) {
            return ASYNC_NO_JOBS;
        }
        if (args != NULL) {
            async_get_ctx()->currjob->funcargs = OPENSSL_malloc(size);
            if (async_get_ctx()->currjob->funcargs == NULL) {
                ASYNCerr(ASYNC_F_ASYNC_START_JOB, ERR_R_MALLOC_FAILURE);
                async_release_job(async_get_ctx()->currjob);
                async_get_ctx()->currjob = NULL;
                return ASYNC_ERR;
            }
            memcpy(async_get_ctx()->currjob->funcargs, args, size);
        } else {
            async_get_ctx()->currjob->funcargs = NULL;
        }
        async_get_ctx()->currjob->func = func;
        if (!async_fibre_swapcontext(&async_get_ctx()->dispatcher,
                &async_get_ctx()->currjob->fibrectx, 1)) {
            ASYNCerr(ASYNC_F_ASYNC_START_JOB, ASYNC_R_FAILED_TO_SWAP_CONTEXT);
            goto err;
        }
    }
err:
    async_release_job(async_get_ctx()->currjob);
    async_get_ctx()->currjob = NULL;
    *job = NULL;
    return ASYNC_ERR;
}
['int ASYNC_start_job(ASYNC_JOB **job, int *ret, int (*func)(void *),\n                         void *args, size_t size)\n{\n    if (async_get_ctx() == NULL && async_ctx_new() == NULL) {\n        return ASYNC_ERR;\n    }\n    if (*job) {\n        async_get_ctx()->currjob = *job;\n    }\n    for (;;) {\n        if (async_get_ctx()->currjob != NULL) {\n            if (async_get_ctx()->currjob->status == ASYNC_JOB_STOPPING) {\n                *ret = async_get_ctx()->currjob->ret;\n                async_release_job(async_get_ctx()->currjob);\n                async_get_ctx()->currjob = NULL;\n                *job = NULL;\n                return ASYNC_FINISH;\n            }\n            if (async_get_ctx()->currjob->status == ASYNC_JOB_PAUSING) {\n                *job = async_get_ctx()->currjob;\n                async_get_ctx()->currjob->status = ASYNC_JOB_PAUSED;\n                async_get_ctx()->currjob = NULL;\n                return ASYNC_PAUSE;\n            }\n            if (async_get_ctx()->currjob->status == ASYNC_JOB_PAUSED) {\n                async_get_ctx()->currjob = *job;\n                if (!async_fibre_swapcontext(&async_get_ctx()->dispatcher,\n                        &async_get_ctx()->currjob->fibrectx, 1)) {\n                    ASYNCerr(ASYNC_F_ASYNC_START_JOB,\n                             ASYNC_R_FAILED_TO_SWAP_CONTEXT);\n                    goto err;\n                }\n                continue;\n            }\n            ASYNCerr(ASYNC_F_ASYNC_START_JOB, ERR_R_INTERNAL_ERROR);\n            async_release_job(async_get_ctx()->currjob);\n            async_get_ctx()->currjob = NULL;\n            *job = NULL;\n            return ASYNC_ERR;\n        }\n        if ((async_get_ctx()->currjob = async_get_pool_job()) == NULL) {\n            return ASYNC_NO_JOBS;\n        }\n        if (args != NULL) {\n            async_get_ctx()->currjob->funcargs = OPENSSL_malloc(size);\n            if (async_get_ctx()->currjob->funcargs == NULL) {\n                ASYNCerr(ASYNC_F_ASYNC_START_JOB, ERR_R_MALLOC_FAILURE);\n                async_release_job(async_get_ctx()->currjob);\n                async_get_ctx()->currjob = NULL;\n                return ASYNC_ERR;\n            }\n            memcpy(async_get_ctx()->currjob->funcargs, args, size);\n        } else {\n            async_get_ctx()->currjob->funcargs = NULL;\n        }\n        async_get_ctx()->currjob->func = func;\n        if (!async_fibre_swapcontext(&async_get_ctx()->dispatcher,\n                &async_get_ctx()->currjob->fibrectx, 1)) {\n            ASYNCerr(ASYNC_F_ASYNC_START_JOB, ASYNC_R_FAILED_TO_SWAP_CONTEXT);\n            goto err;\n        }\n    }\nerr:\n    async_release_job(async_get_ctx()->currjob);\n    async_get_ctx()->currjob = NULL;\n    *job = NULL;\n    return ASYNC_ERR;\n}', 'static async_ctx *async_ctx_new(void)\n{\n    async_ctx *nctx = NULL;\n    nctx = OPENSSL_malloc(sizeof (async_ctx));\n    if (nctx == NULL) {\n        ASYNCerr(ASYNC_F_ASYNC_CTX_NEW, ERR_R_MALLOC_FAILURE);\n        goto err;\n    }\n    async_fibre_init_dispatcher(&nctx->dispatcher);\n    nctx->currjob = NULL;\n    nctx->blocked = 0;\n    if (!async_set_ctx(nctx))\n        goto err;\n    return nctx;\nerr:\n    OPENSSL_free(nctx);\n    return NULL;\n}', 'void *CRYPTO_malloc(size_t num, const char *file, int line)\n{\n    void *ret = NULL;\n    if (num <= 0)\n        return NULL;\n    allow_customize = 0;\n#ifndef OPENSSL_NO_CRYPTO_MDEBUG\n    if (call_malloc_debug) {\n        CRYPTO_mem_debug_malloc(NULL, num, 0, file, line);\n        ret = malloc(num);\n        CRYPTO_mem_debug_malloc(ret, num, 1, file, line);\n    } else {\n        ret = malloc(num);\n    }\n#else\n    (void)file;\n    (void)line;\n    ret = malloc(num);\n#endif\n#ifndef OPENSSL_CPUID_OBJ\n    if (ret && (num > 2048)) {\n        extern unsigned char cleanse_ctr;\n        ((unsigned char *)ret)[0] = cleanse_ctr;\n    }\n#endif\n    return ret;\n}']