static ASYNC_JOB *async_get_pool_job(void) { ASYNC_JOB *job; async_pool *pool; pool = (async_pool *)CRYPTO_THREAD_get_local(&poolkey); if (pool == NULL) { /* * Pool has not been initialised, so init with the defaults, i.e. * no max size and no pre-created jobs */ if (ASYNC_init_thread(0, 0) == 0) return NULL; pool = (async_pool *)CRYPTO_THREAD_get_local(&poolkey); } job = sk_ASYNC_JOB_pop(pool->jobs); if (job == NULL) { /* Pool is empty */ if ((pool->max_size != 0) && (pool->curr_size >= pool->max_size)) return NULL; job = async_job_new(); if (job != NULL) { if (! async_fibre_makecontext(&job->fibrectx)) { async_job_free(job); return NULL; } pool->curr_size++; } } return job; }
int ASYNC_init_thread(size_t max_size, size_t init_size) { async_pool *pool; size_t curr_size = 0; if (init_size > max_size) { ASYNCerr(ASYNC_F_ASYNC_INIT_THREAD, ASYNC_R_INVALID_POOL_SIZE); return 0; } if (!OPENSSL_init_crypto(OPENSSL_INIT_ASYNC, NULL)) { return 0; } if (!ossl_init_thread_start(OPENSSL_INIT_THREAD_ASYNC)) { return 0; } pool = OPENSSL_zalloc(sizeof(*pool)); if (pool == NULL) { ASYNCerr(ASYNC_F_ASYNC_INIT_THREAD, ERR_R_MALLOC_FAILURE); return 0; } pool->jobs = sk_ASYNC_JOB_new_reserve(NULL, init_size); if (pool->jobs == NULL) { ASYNCerr(ASYNC_F_ASYNC_INIT_THREAD, 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; job = async_job_new(); if (job == NULL || !async_fibre_makecontext(&job->fibrectx)) { /* * Not actually fatal because we already created the pool, just * skip creation of any more jobs */ async_job_free(job); break; } job->funcargs = NULL; sk_ASYNC_JOB_push(pool->jobs, job); /* Cannot fail due to reserve */ curr_size++; } pool->curr_size = curr_size; if (!CRYPTO_THREAD_set_local(&poolkey, pool)) { ASYNCerr(ASYNC_F_ASYNC_INIT_THREAD, ASYNC_R_FAILED_TO_SET_POOL); goto err; } return 1; err: async_free_pool_internal(pool); return 0; }
int ASYNC_init_thread(size_t max_size, size_t init_size) { async_pool *pool; size_t curr_size = 0; if (init_size > max_size) { ASYNCerr(ASYNC_F_ASYNC_INIT_THREAD, ASYNC_R_INVALID_POOL_SIZE); return 0; } if (!async_local_init()) { ASYNCerr(ASYNC_F_ASYNC_INIT_THREAD, ASYNC_R_INIT_FAILED); return 0; } pool = OPENSSL_zalloc(sizeof *pool); if (pool == NULL) { ASYNCerr(ASYNC_F_ASYNC_INIT_THREAD, ERR_R_MALLOC_FAILURE); return 0; } pool->jobs = sk_ASYNC_JOB_new_null(); if (pool->jobs == NULL) { ASYNCerr(ASYNC_F_ASYNC_INIT_THREAD, 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; job = async_job_new(); if (job == NULL || !async_fibre_makecontext(&job->fibrectx)) { /* * Not actually fatal because we already created the pool, just * skip creation of any more jobs */ async_job_free(job); break; } job->funcargs = NULL; sk_ASYNC_JOB_push(pool->jobs, job); curr_size++; } pool->curr_size = curr_size; if (!async_set_pool(pool)) { ASYNCerr(ASYNC_F_ASYNC_INIT_THREAD, ASYNC_R_FAILED_TO_SET_POOL); goto err; } return 1; err: async_free_pool_internal(pool); return 0; }
static void async_empty_pool(async_pool *pool) { ASYNC_JOB *job; if (!pool || !pool->jobs) return; do { job = sk_ASYNC_JOB_pop(pool->jobs); async_job_free(job); } while (job); }
/** * main_entry: * * Main function of RetroArch. * * If HAVE_MAIN is not defined, will contain main loop and will not * be exited from until we exit the program. Otherwise, will * just do initialization. * * Returns: varies per platform. **/ int rarch_main(int argc, char *argv[], void *data) { void *args = (void*)data; int ret = 0; settings_t *settings = NULL; rarch_ctl(RARCH_CTL_PREINIT, NULL); frontend_driver_init_first(args); rarch_ctl(RARCH_CTL_INIT, NULL); #ifdef HAVE_THREADS async_jobs = async_job_new(); #endif if (frontend_driver_is_inited()) { ret = main_load_content(argc, argv, args, frontend_driver_environment_get_ptr()); if (!ret) return ret; } event_cmd_ctl(EVENT_CMD_HISTORY_INIT, NULL); settings = config_get_ptr(); if (settings->history_list_enable) { char *fullpath = NULL; rarch_system_info_t *system = NULL; runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &system); runloop_ctl(RUNLOOP_CTL_GET_CONTENT_PATH, &fullpath); if (content_ctl(CONTENT_CTL_IS_INITED, NULL) || system->no_content) history_playlist_push( g_defaults.history, fullpath, settings->libretro, system ? &system->info : NULL); } ui_companion_driver_init_first(); #ifndef HAVE_MAIN do { unsigned sleep_ms = 0; ret = runloop_iterate(&sleep_ms); if (ret == 1 && sleep_ms > 0) retro_sleep(sleep_ms); runloop_ctl(RUNLOOP_CTL_DATA_ITERATE, NULL); }while(ret != -1); main_exit(args); #endif #ifdef HAVE_THREADS async_job_free(async_jobs); async_jobs = NULL; #endif return 0; }