|
|
@ -2,15 +2,7 @@ |
|
|
|
#include "erl_nif.h"
|
|
|
|
#include "concurrentqueue.h"
|
|
|
|
|
|
|
|
struct qData { |
|
|
|
ErlNifEnv *env; |
|
|
|
ERL_NIF_TERM term; |
|
|
|
}; |
|
|
|
|
|
|
|
struct lfqIns { |
|
|
|
moodycamel::ConcurrentQueue<qData> *LFQ; |
|
|
|
moodycamel::ConcurrentQueue<ErlNifEnv *> *G_ENV; |
|
|
|
}; |
|
|
|
using lfqIns = moodycamel::ConcurrentQueue<ErlNifBinary> *; |
|
|
|
|
|
|
|
ERL_NIF_TERM atomOk; |
|
|
|
ERL_NIF_TERM atomError; |
|
|
@ -31,19 +23,13 @@ ERL_NIF_TERM make_error(ErlNifEnv *env, const char *error) { |
|
|
|
|
|
|
|
void eLfqFree(ErlNifEnv *, void *obj) { |
|
|
|
lfqIns *ObjIns = static_cast<lfqIns *>(obj); |
|
|
|
|
|
|
|
if (ObjIns != nullptr) { |
|
|
|
qData Data; |
|
|
|
while (ObjIns->LFQ->try_dequeue(Data)) { |
|
|
|
enif_free_env(Data.env); |
|
|
|
ErlNifBinary TermBin; |
|
|
|
while ((*ObjIns)->try_dequeue(TermBin)) { |
|
|
|
enif_release_binary(&TermBin); |
|
|
|
} |
|
|
|
|
|
|
|
ErlNifEnv *StoreEnv; |
|
|
|
while (ObjIns->G_ENV->try_dequeue(StoreEnv)) { |
|
|
|
enif_free_env(StoreEnv); |
|
|
|
} |
|
|
|
delete ObjIns->LFQ; |
|
|
|
delete ObjIns->G_ENV; |
|
|
|
delete ObjIns; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@ -81,16 +67,15 @@ void nifUnload(ErlNifEnv *, void *priv_data) { |
|
|
|
ERL_NIF_TERM nifNew(ErlNifEnv *env, int, const ERL_NIF_TERM *) { |
|
|
|
ErlNifResourceType *ResIns = static_cast<ErlNifResourceType *>(enif_priv_data(env)); |
|
|
|
|
|
|
|
lfqIns *ObjIns = static_cast<lfqIns *>(enif_alloc_resource(ResIns, sizeof(lfqIns))); |
|
|
|
ObjIns->LFQ = new moodycamel::ConcurrentQueue<qData>; |
|
|
|
ObjIns->G_ENV = new moodycamel::ConcurrentQueue<ErlNifEnv *>; |
|
|
|
lfqIns* ObjIns = static_cast<lfqIns *>(enif_alloc_resource(ResIns, sizeof(lfqIns))); |
|
|
|
*ObjIns = new moodycamel::ConcurrentQueue<ErlNifBinary>; |
|
|
|
|
|
|
|
if (ObjIns == NULL) |
|
|
|
return make_error(env, "enif_alloc_resource failed"); |
|
|
|
|
|
|
|
ERL_NIF_TERM term = enif_make_resource(env, ObjIns); |
|
|
|
ERL_NIF_TERM RefTerm = enif_make_resource(env, ObjIns); |
|
|
|
enif_release_resource(ResIns); |
|
|
|
return enif_make_tuple2(env, atomOk, term); |
|
|
|
return enif_make_tuple2(env, atomOk, RefTerm); |
|
|
|
} |
|
|
|
|
|
|
|
ERL_NIF_TERM nifIn2(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) { |
|
|
@ -102,42 +87,18 @@ ERL_NIF_TERM nifIn2(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) { |
|
|
|
return enif_make_badarg(env); |
|
|
|
} |
|
|
|
|
|
|
|
qData InTerm; |
|
|
|
|
|
|
|
InTerm.env = enif_alloc_env(); |
|
|
|
InTerm.term = enif_make_copy(InTerm.env, argv[1]); |
|
|
|
ErlNifBinary TermBin; |
|
|
|
if(!enif_term_to_binary(env, argv[1], &TermBin)) |
|
|
|
return enif_make_badarg(env); |
|
|
|
|
|
|
|
if (ObjIns->LFQ->enqueue(InTerm)){ |
|
|
|
if ((*ObjIns)->enqueue(TermBin)){ |
|
|
|
return atomTrue; |
|
|
|
} else { |
|
|
|
enif_release_binary(&TermBin); |
|
|
|
return atomFalse; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// ERL_NIF_TERM nifIn2(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
|
|
|
|
// ErlNifResourceType* ResIns = static_cast<ErlNifResourceType *>(enif_priv_data(env));
|
|
|
|
//
|
|
|
|
// lfqIns *ObjIns = NULL;
|
|
|
|
//
|
|
|
|
// if (!enif_get_resource(env, argv[0], ResIns, (void **) &ObjIns)) {
|
|
|
|
// return enif_make_badarg(env);
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// qData InTerm;
|
|
|
|
// if (ObjIns->G_ENV->try_dequeue(InTerm.env) != true) {
|
|
|
|
// InTerm.env = enif_alloc_env();
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// InTerm.term = enif_make_copy(InTerm.env, argv[1]);
|
|
|
|
//
|
|
|
|
// if (ObjIns->LFQ->enqueue(InTerm)){
|
|
|
|
// return atomTrue;
|
|
|
|
// } else {
|
|
|
|
// return atomFalse;
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
ERL_NIF_TERM nifIn3(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) { |
|
|
|
return atomTrue; |
|
|
|
} |
|
|
@ -174,46 +135,24 @@ ERL_NIF_TERM nifTryOut1(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) { |
|
|
|
return enif_make_badarg(env); |
|
|
|
} |
|
|
|
|
|
|
|
ERL_NIF_TERM OutTerm; |
|
|
|
qData Data; |
|
|
|
ErlNifBinary TermBin; |
|
|
|
|
|
|
|
if (ObjIns->LFQ->try_dequeue(Data)) { |
|
|
|
OutTerm = enif_make_copy(env, Data.term); |
|
|
|
enif_free_env(Data.env); |
|
|
|
return enif_make_tuple2(env, atomOk, OutTerm); |
|
|
|
if ((*ObjIns)->try_dequeue(TermBin)) { |
|
|
|
ERL_NIF_TERM OutTerm; |
|
|
|
if(enif_binary_to_term(env, TermBin.data, TermBin.size, &OutTerm, 0) == 0) |
|
|
|
{ |
|
|
|
enif_release_binary(&TermBin); |
|
|
|
// return make_error(env, atomError "failed to decode data");
|
|
|
|
return atomError; |
|
|
|
} else{ |
|
|
|
enif_release_binary(&TermBin); |
|
|
|
return enif_make_tuple2(env, atomOk, OutTerm); |
|
|
|
} |
|
|
|
} else { |
|
|
|
return atomEmpty; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// ERL_NIF_TERM nifTryOut1(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
|
|
|
|
// ErlNifResourceType* ResIns = static_cast<ErlNifResourceType *>(enif_priv_data(env));
|
|
|
|
// lfqIns *ObjIns = NULL;
|
|
|
|
//
|
|
|
|
// if (!enif_get_resource(env, argv[0], ResIns, (void **) &ObjIns)) {
|
|
|
|
// return enif_make_badarg(env);
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// ERL_NIF_TERM OutTerm;
|
|
|
|
// qData Data;
|
|
|
|
//
|
|
|
|
// if (ObjIns->LFQ->try_dequeue(Data)) {
|
|
|
|
// OutTerm = enif_make_copy(env, Data.term);
|
|
|
|
//
|
|
|
|
// if(ObjIns->G_ENV->size_approx() > 1000){
|
|
|
|
// enif_free_env(Data.env);
|
|
|
|
// }else{
|
|
|
|
// enif_clear_env(Data.env);
|
|
|
|
// if (!ObjIns->G_ENV->enqueue(Data.env)){
|
|
|
|
// enif_free_env(Data.env);
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// return enif_make_tuple2(env, atomOk, OutTerm);
|
|
|
|
// } else {
|
|
|
|
// return atomEmpty;
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
ERL_NIF_TERM nifTryOut2(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) { |
|
|
|
return atomEmpty; |
|
|
|
} |
|
|
|