Question

I have written an Erlang C NIF that returns a pointer to a structure after calling new and for now just increments a variable on insert. I am wondering how to properly destroy the original resource, or at least mark it for GC. I am having no luck.

#include <stdio.h> 
#include "erl_nif.h"


typedef struct level {
    float a;
    float b;
} LVL;

// data array with key being the price
typedef struct book {
    int array_size; // # of TTL indices
    int len; // # of Occupied indices (inc. val) from bestPriceIndex
    int max_len; 

    LVL lvl_data[];

} Book;


static ErlNifResourceType *MEM_RESOURCE;


    static int
on_load(ErlNifEnv *env, void **priv_data, ERL_NIF_TERM load_info)
{
    ErlNifResourceFlags flags = (ErlNifResourceFlags)(ERL_NIF_RT_CREATE);

    if ( (MEM_RESOURCE = enif_open_resource_type(env, 
            NULL,
            "mem_resource", 
            NULL, //dtor
            flags, 
            NULL)) == NULL)
        return -1;

    return 0;
}


    static ERL_NIF_TERM 
new( ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[] ) 
{   
    int max_len = 50;

    int mem_size = sizeof(Book) + max_len * sizeof(LVL);
    Book *q = enif_alloc_resource(MEM_RESOURCE, mem_size );
        if( q == NULL ) return enif_make_string(env, "could not alloc", ERL_NIF_LATIN1);

    q->lvl_data[0].a = 7.0;     

    ERL_NIF_TERM term = enif_make_resource(env, q);

    enif_release_resource(q);

    return term;
};


    static ERL_NIF_TERM 
insert( ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[] ) 
{
    Book *p;
    if (!enif_get_resource(env, argv[0], MEM_RESOURCE, (void **)&p)) 
       return enif_make_badarg(env); 

    float x = ++p->lvl_data[0].a;

    return enif_make_string(env, "okk", ERL_NIF_LATIN1);
};


static ErlNifFunc nif_funcs[] = 
{ 
    {"new", 0, new},
    {"insert", 1, insert}
};

ERL_NIF_INIT( test, nif_funcs, on_load, NULL, NULL, NULL )
Was it helpful?

Solution

When there are no terms holding the resource, the resource will be collected automatically by GC.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top