static int on_load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info) { ErlNifResourceFlags flags = (ErlNifResourceFlags)(ERL_NIF_RT_CREATE | ERL_NIF_RT_TAKEOVER); ErlNifResourceType* rt = enif_open_resource_type(env, NULL, "cqueue_resource", &cqueue_resource_cleanup, flags, NULL); if (rt == NULL) return -1; cqueue_RESOURCE = rt; ErlNifSysInfo sys_info; enif_system_info(&sys_info, sizeof(ErlNifSysInfo)); schedulers = sys_info.scheduler_threads; scheduler_ids = new ErlNifTid[schedulers]; for (unsigned int i = 0; i < schedulers; ++i) { scheduler_ids[i] = NULL; } lookup_lock = enif_rwlock_create("cqueue_lookup_lock"); return 0; }
static int have_dirty_schedulers(void) { ErlNifSysInfo si; enif_system_info(&si, sizeof(si)); return si.dirty_scheduler_support; }
static int initialize(ErlNifEnv* env, ERL_NIF_TERM load_info) { #ifdef OPENSSL_THREADS ErlNifSysInfo sys_info; #endif get_crypto_callbacks_t* funcp; struct crypto_callbacks* ccb; int nlocks = 0; int tpl_arity; const ERL_NIF_TERM* tpl_array; int vernum; ErlNifBinary lib_bin; char lib_buf[1000]; #ifdef HAVE_DYNAMIC_CRYPTO_LIB void *handle; #endif if (!verify_lib_version()) return __LINE__; /* load_info: {302, <<"/full/path/of/this/library">>,true|false} */ if (!enif_get_tuple(env, load_info, &tpl_arity, &tpl_array)) return __LINE__; if (tpl_arity != 3) return __LINE__; if (!enif_get_int(env, tpl_array[0], &vernum)) return __LINE__; if (vernum != 302) return __LINE__; if (!enif_inspect_binary(env, tpl_array[1], &lib_bin)) return __LINE__; if (!init_hmac_ctx(env)) { return __LINE__; } if (!init_hash_ctx(env)) { return __LINE__; } if (!init_cipher_ctx(env)) { return __LINE__; } if (!init_engine_ctx(env)) { return __LINE__; } if (library_initialized) { /* Repeated loading of this library (module upgrade). * Atoms and callbacks are already set, we are done. */ return 0; } if (!init_atoms(env, tpl_array[2], load_info)) { return __LINE__; } #ifdef HAVE_DYNAMIC_CRYPTO_LIB if (!change_basename(&lib_bin, lib_buf, sizeof(lib_buf), crypto_callback_name)) return __LINE__; if ((handle = enif_dlopen(lib_buf, &error_handler, NULL)) == NULL) return __LINE__; if ((funcp = (get_crypto_callbacks_t*) enif_dlsym(handle, "get_crypto_callbacks", &error_handler, NULL)) == NULL) return __LINE__; #else /* !HAVE_DYNAMIC_CRYPTO_LIB */ funcp = &get_crypto_callbacks; #endif #ifdef OPENSSL_THREADS enif_system_info(&sys_info, sizeof(sys_info)); if (sys_info.scheduler_threads > 1) { nlocks = CRYPTO_num_locks(); } /* else no need for locks */ #endif ccb = (*funcp)(nlocks); if (!ccb || ccb->sizeof_me != sizeof(*ccb)) { PRINTF_ERR0("Invalid 'crypto_callbacks'"); return __LINE__; } #ifdef HAS_CRYPTO_MEM_FUNCTIONS if (!CRYPTO_set_mem_functions(ccb->crypto_alloc, ccb->crypto_realloc, ccb->crypto_free)) return __LINE__; #endif #ifdef OPENSSL_THREADS if (nlocks > 0) { CRYPTO_set_locking_callback(ccb->locking_function); CRYPTO_set_id_callback(ccb->id_function); CRYPTO_set_dynlock_create_callback(ccb->dyn_create_function); CRYPTO_set_dynlock_lock_callback(ccb->dyn_lock_function); CRYPTO_set_dynlock_destroy_callback(ccb->dyn_destroy_function); } #endif /* OPENSSL_THREADS */ init_digest_types(env); init_cipher_types(env); init_algorithms_types(env); library_initialized = 1; return 0; }