NIFs and lists of resources

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

NIFs and lists of resources

Jordan Day-2
Apologies that this is more of a C question than an Erlang question…

I’m working on a NIF accessing a vendor’s C API and wondering what the correct approach is to handling a function from which I’d like to return a list of resources. While my functions handling individual resources seem to be working as expected (calling the destructors when the item is GC’d on the erlang side), I’m not seeing that happen with a function where I’m returning a list of resources.

In code where I’d normally do something like
vendor_template templates[num_templates];
fill_templates(templates);
...
return templates;


I’d like each vendor_template struct to become a resource I can pass around and have GC’d when I’m done with them, on a per-item basis. I presumed I could do the normal resource-related calls and then return an erlang list, but I’m not seeing the destructor function called when the list should be getting GC’d on the erlang side.

Example:

vendor_template *templates = enif_alloc_resource(TEMPLATE_TYPE, sizeof(vendor_template) * num_templates);
ERL_NIF_TERM template_res[num_templates];
fill_templates(templates);
for (int i = 0; i < num_templates; i++) {
  template_res[i] = enif_make_resource(env, &(templates[i]));
  enif_release_resource(&(templates[i]));
}

ERL_NIF_TERM template_list = enif_make_list_from_array(env, template_res, num_templates);
return template_list;

The returned list of resources seem to be correct, as I can use their individual references in subsequent NIF calls, but when the returned list is discarded, I never see the destructor function called.

Any tips on what I might be doing wrong? Does the enif_make_list_from_array/2 call “break” this? If so, how can I return my list of resources?

Regards,
Jordan

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: NIFs and lists of resources

Sverker Eriksson-5
Each call to enif_alloc_resource() returns ONE resource object.

enif_make_resource expects a pointer returned from enif_alloc_resource(),
and only your &templates [0] is such a pointer.

So, you probable want to call enif_alloc_resource one time for every resource in your array/list.


/Sverker

On ons, 2018-09-19 at 13:32 -0500, Jordan Day wrote:
Apologies that this is more of a C question than an Erlang question…

I’m working on a NIF accessing a vendor’s C API and wondering what the correct approach is to handling a function from which I’d like to return a list of resources. While my functions handling individual resources seem to be working as expected (calling the destructors when the item is GC’d on the erlang side), I’m not seeing that happen with a function where I’m returning a list of resources.

In code where I’d normally do something like
vendor_template templates[num_templates];
fill_templates(templates);
...
return templates;


I’d like each vendor_template struct to become a resource I can pass around and have GC’d when I’m done with them, on a per-item basis. I presumed I could do the normal resource-related calls and then return an erlang list, but I’m not seeing the destructor function called when the list should be getting GC’d on the erlang side.

Example:

vendor_template *templates = enif_alloc_resource(TEMPLATE_TYPE, sizeof(vendor_template) * num_templates);
ERL_NIF_TERM template_res[num_templates];
fill_templates(templates);
for (int i = 0; i < num_templates; i++) {
  template_res[i] = enif_make_resource(env, &(templates[i]));
  enif_release_resource(&(templates[i]));
}

ERL_NIF_TERM template_list = enif_make_list_from_array(env, template_res, num_templates);
return template_list;

The returned list of resources seem to be correct, as I can use their individual references in subsequent NIF calls, but when the returned list is discarded, I never see the destructor function called.

Any tips on what I might be doing wrong? Does the enif_make_list_from_array/2 call “break” this? If so, how can I return my list of resources?

Regards,
Jordan
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions