/* * Start the processing thread */ static ERL_NIF_TERM esqlite_start(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { esqlite_connection *conn; ERL_NIF_TERM db_conn; /* Initialize the resource */ conn = enif_alloc_resource(esqlite_connection_type, sizeof(esqlite_connection)); if(!conn) return make_error_tuple(env, "no_memory"); conn->db = NULL; /* Create command queue */ conn->commands = queue_create(); if(!conn->commands) { enif_release_resource(conn); return make_error_tuple(env, "command_queue_create_failed"); } /* Start command processing thread */ conn->opts = enif_thread_opts_create("esqldb_thread_opts"); if(enif_thread_create("esqlite_connection", &conn->tid, esqlite_connection_run, conn, conn->opts) != 0) { enif_release_resource(conn); return make_error_tuple(env, "thread_create_failed"); } db_conn = enif_make_resource(env, conn); enif_release_resource(conn); return make_ok_tuple(env, db_conn); }
static ERL_NIF_TERM send_blob_thread(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { union { void* vp; struct make_term_info* p; }mti; ERL_NIF_TERM copy; if (!enif_get_resource(env, argv[0], msgenv_resource_type, &mti.vp) || !enif_get_local_pid(env,argv[1], &mti.p->to_pid)) { return enif_make_badarg(env); } copy = enif_make_copy(env, mti.p->blob); mti.p->send_it = enif_is_identical(argv[2],atom_join); if (enif_thread_create("nif_SUITE:send_from_thread", &mti.p->tid, threaded_sender, mti.p, NULL) != 0) { return enif_make_badarg(env); } if (enif_is_identical(argv[2],atom_join)) { int err = enif_thread_join(mti.p->tid, NULL); assert(err == 0); return enif_make_tuple3(env, atom_ok, enif_make_int(env, mti.p->send_res), copy); } else { enif_keep_resource(mti.vp); return enif_make_tuple2(env, atom_ok, copy); } }
static int load(ErlNifEnv* env, void** priv, ERL_NIF_TERM load_info) { state_t* state = (state_t*) enif_alloc(sizeof(state_t)); if(state == NULL) return -1; state->queue = queue_create(); if(state->queue == NULL) goto error; state->opts = enif_thread_opts_create("thread_opts"); if(enif_thread_create( "", &(state->qthread), thr_main, state, state->opts ) != 0) { goto error; } state->atom_ok = enif_make_atom(env, "ok"); *priv = (void*) state; return 0; error: if(state->queue != NULL) queue_destroy(state->queue); //enif_free(state->queue); //double free bug ( already called free at queue_destroy() ) return -1; }
static ERL_NIF_TERM _listener (ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { CAN_handle* handle; ErlNifPid pid = { 0 }; // NOTE: breaking opaque type! enif_get_resource(env, argv[0], CAN_handle_type, (void**) &handle); if (handle->threaded) // there is a thread already and some pid! { pid = handle->receiver; } if (!enif_get_local_pid(env, argv[1], &handle->receiver)) // NOTE: use lock if pid type is structural! { handle->threaded = 0; return enif_make_badarg(env); } else { enif_get_uint(env, argv[2], &handle->chunk_size); enif_get_long(env, argv[3], &handle->timeout); if (!handle->threaded) // a thread was not created already { if (enif_thread_create("can_reading_thread", &handle->tid, _reading_thread, handle, 0)) { handle->threaded = 0; return enif_make_int(env, -1004); } } } return pid.pid ? enif_make_pid(env, &pid) : enif_make_int(env, 0); }
ctx_t* init_ctx() { int status; ctx_t *ctx = static_cast<ctx_t*>(enif_alloc_resource(res_type, sizeof(*ctx))); if (ctx == NULL) { goto done; } ctx->queue = async_queue_create(); ctx->topts = enif_thread_opts_create(const_cast<char*>("snappy_thread_opts")); status = enif_thread_create(const_cast<char*>("worker"), &ctx->tid, worker, ctx, ctx->topts); if (status != 0) { enif_release_resource(ctx); ctx = NULL; goto done; } done: return ctx; }
static bool start_workers() { worker_threads = (ErlNifTid *) enif_alloc(sizeof(ErlNifTid) * workers); if (!worker_threads) { return false; } for (int i = 0; i < workers; i++) { enif_thread_create("brine_worker_thread", &worker_threads[i], worker_loop, NULL, NULL); } return true; }
static ERL_NIF_TERM MakeTestCall(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { TCall *call = (TCall *)malloc(sizeof(TCall)); call->env = env; call->fun = argv[0]; call->args = argv[1]; enif_thread_create("my_thread", &tid, TestCall, (void *)call, NULL); return enif_make_atom(env, "ok"); }
void* nif_create_main_thread(char* name) { nif_thread_state* st = (nif_thread_state*)enif_alloc(sizeof(nif_thread_state)); st->lock = enif_mutex_create("esdl2_lock"); st->cond = enif_cond_create("esdl2_cond"); st->mailbox = (nif_thread_mailbox*)enif_alloc(sizeof(nif_thread_mailbox)); TAILQ_INIT(st->mailbox); enif_thread_create(name, &(st->tid), nif_main_thread, st, NULL); return (void*)st; }
static nif_term_t start(nif_heap_t *hp, int argc, const nif_term_t argv[]) { struct salt_pcb *sc; nif_cond_t *cv; nif_lock_t *lk; nif_term_t pcb; if (argc != 0) return (BADARG); /* Create thread control block, pass ownership to Erlang. */ assert(salt_pcb_type != NULL); sc = enif_alloc_resource(salt_pcb_type, sizeof(*sc)); if (sc == NULL) goto fail_0; cv = enif_cond_create("lots_pcb_cv"); if (cv == NULL) goto fail_1; lk = enif_mutex_create("lots_pcb_lock"); if (lk == NULL) goto fail_2; sc->sc_vsn = SALT_VSN(1, 0, 0); sc->sc_lock = lk; sc->sc_cond = cv; sc->sc_req_first = NULL; sc->sc_req_lastp = &sc->sc_req_first; sc->sc_req_npend = 0; sc->sc_exit_flag = false; if (enif_thread_create("salt_thread", &sc->sc_thread, salt_worker_loop, sc, NULL) != 0) goto fail_3; pcb = enif_make_resource(hp, sc); enif_release_resource(sc); return (pcb); /* Failure handling. */ fail_3: enif_mutex_destroy(lk); fail_2: enif_cond_destroy(cv); fail_1: enif_release_resource(sc); fail_0: return (BADARG); }
static ERL_NIF_TERM nif_pcap_loop(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { EWPCAP_STATE *ep = NULL; if (!enif_get_resource(env, argv[0], EWPCAP_RESOURCE, (void **)&ep) || ep->p == NULL) return enif_make_badarg(env); if (enif_thread_create("ewpcap_loop", &ep->tid, ewpcap_loop, ep, NULL) != 0) return enif_make_tuple2(env, atom_error, enif_make_atom(env, erl_errno_id(errno))); return atom_ok; }
static struct cache * new_cache(ERL_NIF_TERM atom, int max_size, int min_q1_size) { struct cache *c; struct atom_node *an; int i; c = enif_alloc(sizeof(*c)); memset(c, 0, sizeof(*c)); c->max_size = max_size; c->min_q1_size = min_q1_size; c->lookup_lock = enif_rwlock_create("cache->lookup_lock"); c->cache_lock = enif_rwlock_create("cache->cache_lock"); c->ctrl_lock = enif_mutex_create("cache->ctrl_lock"); c->check_cond = enif_cond_create("cache->check_cond"); TAILQ_INIT(&(c->q1.head)); TAILQ_INIT(&(c->q2.head)); for (i = 0; i < N_INCR_BKT; ++i) { TAILQ_INIT(&(c->incr_head[i])); c->incr_lock[i] = enif_mutex_create("cache->incr_lock"); } RB_INIT(&(c->expiry_head)); an = enif_alloc(sizeof(*an)); memset(an, 0, sizeof(*an)); an->atom = enif_make_copy(gbl->atom_env, atom); an->cache = c; c->atom_node = an; enif_rwlock_rwlock(gbl->atom_lock); RB_INSERT(atom_tree, &(gbl->atom_head), an); /* start the background thread for the cache. after this, the bg thread now owns the cache and all its data and will free it at exit */ enif_thread_create("cachethread", &(c->bg_thread), cache_bg_thread, c, NULL); enif_rwlock_rwunlock(gbl->atom_lock); return c; }
vm_ptr vm_init(ErlNifResourceType* res_type, JSRuntime* runtime, size_t stack_size) { vm_ptr vm = (vm_ptr) enif_alloc_resource(res_type, sizeof(struct vm_t)); if(vm == NULL) return NULL; vm->runtime = runtime; vm->curr_job = NULL; vm->stack_size = stack_size; vm->jobs = queue_create(); if(vm->jobs == NULL) goto error; vm->opts = enif_thread_opts_create("vm_thread_opts"); if(enif_thread_create("", &vm->tid, vm_run, vm, vm->opts) != 0) goto error; return vm; error: enif_release_resource(vm); return NULL; }
static ERL_NIF_TERM alsa_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { int sample_rate, channels; int selected_device = -1; enif_get_int(env, argv[0], &sample_rate); enif_get_int(env, argv[1], &channels); if(argc > 2) { enif_get_int(env, argv[2], &selected_device); } // selectedDevice = dump_audio_info(selectedDevice); AudioCapture *capture = (AudioCapture *)enif_alloc_resource(alsa_resource, sizeof(AudioCapture)); bzero(capture, sizeof(AudioCapture)); capture->sample_rate = sample_rate; capture->channels = channels; capture->frame_size = capture->channels*2*1024; capture->selected_device = selected_device; enif_self(env, &capture->owner_pid); capture->env = enif_alloc_env(); fprintf(stderr, "Starting alsa %d\r\n", capture->sample_rate); capture->thread_started = 1; enif_thread_create("alsa_thread", &capture->tid, capture_thread, capture, NULL); ERL_NIF_TERM port = enif_make_resource(env, capture); capture->port = enif_make_copy(capture->env, port); enif_release_resource(capture); return port; }
int worker_init(worker_t *worker,int id) { struct queue_t *q; ErlNifThreadOpts* opts; q = queue_create(); if(q == NULL ) { goto queue_error; } worker->q = q; worker->id =id; opts = enif_thread_opts_create("lua_thread_opts"); if(opts == NULL) { goto opts_error; } worker->opts = opts; if(enif_thread_create("lua_thread", &worker->tid, worker_run, worker, worker->opts) != 0) { goto create_error; } return 0; create_error: enif_thread_opts_destroy(opts); opts_error: queue_destroy(q); queue_error: return -1; }