#include "enlfq.h"
|
|
#include "enlfq_nif.h"
|
|
|
|
#include "nif_utils.h"
|
|
|
|
#include "concurrentqueue.h"
|
|
|
|
|
|
struct q_item {
|
|
ErlNifEnv *env;
|
|
ERL_NIF_TERM term;
|
|
};
|
|
|
|
struct squeue {
|
|
moodycamel::ConcurrentQueue<q_item> *queue;
|
|
};
|
|
|
|
|
|
void nif_enlfq_free(ErlNifEnv *, void *obj) {
|
|
squeue *inst = static_cast<squeue *>(obj);
|
|
|
|
if (inst != nullptr) {
|
|
q_item item;
|
|
while (inst->queue->try_dequeue(item)) {
|
|
enif_free_env(item.env);
|
|
}
|
|
delete inst->queue;
|
|
}
|
|
}
|
|
|
|
ERL_NIF_TERM nif_enlfq_new(ErlNifEnv *env, int, const ERL_NIF_TERM *) {
|
|
shared_data *data = static_cast<shared_data *>(enif_priv_data(env));
|
|
|
|
|
|
squeue *qinst = static_cast<squeue *>(enif_alloc_resource(data->resQueueInstance, sizeof(squeue)));
|
|
qinst->queue = new moodycamel::ConcurrentQueue<q_item>;
|
|
|
|
if (qinst == NULL)
|
|
return make_error(env, "enif_alloc_resource failed");
|
|
|
|
ERL_NIF_TERM term = enif_make_resource(env, qinst);
|
|
enif_release_resource(qinst);
|
|
return enif_make_tuple2(env, ATOMS.atomOk, term);
|
|
}
|
|
|
|
ERL_NIF_TERM nif_enlfq_push(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
|
|
shared_data *data = static_cast<shared_data *>(enif_priv_data(env));
|
|
|
|
squeue *inst;
|
|
|
|
if (!enif_get_resource(env, argv[0], data->resQueueInstance, (void **) &inst)) {
|
|
return enif_make_badarg(env);
|
|
}
|
|
|
|
q_item item;
|
|
|
|
item.env = enif_alloc_env();
|
|
item.term = enif_make_copy(item.env, argv[1]);
|
|
|
|
inst->queue->enqueue(item);
|
|
|
|
return ATOMS.atomTrue;
|
|
}
|
|
|
|
ERL_NIF_TERM nif_enlfq_pop(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
|
|
shared_data *data = static_cast<shared_data *>(enif_priv_data(env));
|
|
squeue *inst = NULL;
|
|
|
|
if (!enif_get_resource(env, argv[0], data->resQueueInstance, (void **) &inst)) {
|
|
return enif_make_badarg(env);
|
|
}
|
|
|
|
ERL_NIF_TERM term;
|
|
q_item item;
|
|
|
|
if (inst->queue->try_dequeue(item)) {
|
|
term = enif_make_copy(env, item.term);
|
|
enif_free_env(item.env);
|
|
return enif_make_tuple2(env, ATOMS.atomOk, term);
|
|
} else {
|
|
return ATOMS.atomEmpty;
|
|
}
|
|
|
|
}
|