enif_release_resource and enif_make_resource

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

enif_release_resource and enif_make_resource

Max Lapshin-2


I have following code in nif:

State *s = enif_alloc_resource(..)
enif_self(env, &s->owner);
ERL_NIF_TERM term = enif_make_resource(env, s);
enif_release_resource(s);
return term;


Then later another thread (not written by me) is calling my callback function:


void mycallback(void *obj)
{
  State *s = obj;
  ErlNifEnv *msg_env = enif_alloc_env();
  ERL_NIF_TERM term = enif_make_resource(msg_env, s);
  enif_send(NULL, &s->owner, msg_env, term);
  enif_free_env(msg_env);
}


Is this code correct?

Should I put release_resource for each make_resource or only for release_resource?

Is this calling of enif_send correct?

I'm afraid that I miss these answers in documentation or cannot find them. 

  

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

Re: enif_release_resource and enif_make_resource

Mikael Karlsson-7
Thu 4 juli 2019 16:11 Max Lapshin <[hidden email]> wrote:


I have following code in nif:

State *s = enif_alloc_resource(..)
enif_self(env, &s->owner);
ERL_NIF_TERM term = enif_make_resource(env, s);
enif_release_resource(s);
return term;


Then later another thread (not written by me) is calling my callback function:


void mycallback(void *obj)
{
  State *s = obj;
  ErlNifEnv *msg_env = enif_alloc_env();
  ERL_NIF_TERM term = enif_make_resource(msg_env, s);
  enif_send(NULL, &s->owner, msg_env, term);
  enif_free_env(msg_env);
}


Is this code correct?

Should I put release_resource for each make_resource or only for release_resource?

Is this calling of enif_send correct?

I'm afraid that I miss these answers in documentation or cannot find them. 


Your code looks good to me.
I only  call enif_release_resource for references obtained by enif_alloc_resource. If you check the documentation for enif_release_resource I think it is pretty clear about this.
And enif_send looks ok too.
Maybe you will have a problem if the pid used in the callback is from the same object you allocated in the previous statement, then I do not think that you shall call enif_release_resource at all. And if you only wan't to keep the pid for a callback maybe enif_alloc is enough too?
  ErlNifPid* pid = (ErlNifPid*) enif_alloc(sizeof(ErlNifPid));
  enif_self(env, pid);
  ...code to add pid to callback handler..
 and do not call enif_free


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