Beispiel #1
0
    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;
    }
Beispiel #2
0
static int have_dirty_schedulers(void)
{
    ErlNifSysInfo si;
    enif_system_info(&si, sizeof(si));
    return si.dirty_scheduler_support;
}
Beispiel #3
0
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;
}