[erlang-questions] enif_send, how to call off a smp thread?

Vans S vans_163@REDACTED
Tue Mar 21 14:57:04 CET 2017


Iv tried so many combinations of passing the default env in the user_data of the callback/setting a global or setting that to NULL and using the msg_env, same result. Even if I do it like this or that:

static ErlNifPid my_temp_pid;
static void on_callback(void* user_data)
{
ErlNifEnv* msg_env = enif_alloc_env();

enif_send(NULL, &my_temp_pid, msg_env, mk_atom(msg_env, "okk"));
enif_free_env(msg_env);

msg_env = enif_alloc_env();enif_send(NULL, &my_temp_pid, msg_env, mk_atom(msg_env, "aaokk"));
enif_free_env(msg_env);
}


static void on_callback2(void* user_data)
{
ErlNifEnv* msg_env = enif_alloc_env();
enif_send(NULL, &my_temp_pid, msg_env, mk_atom(msg_env, "okk"));
enif_clear_env(msg_env);
enif_send(NULL, &my_temp_pid, msg_env, mk_atom(msg_env, "aaokk"));
enif_free_env(msg_env);
}


Only the first msg comes, its like it caches/remembers it and ignores the rest. I wonder if its due to not being able to
call enif_send from a random non SMP thread and if I need to make a queue that I poll later?

By only the first msg comes, if I later do a enif_send with "okk2" atom as the first, it wont send unless the atom is exactly "okk".

The same thing if you substitute the atom with an integer or binary.

On Tuesday, March 21, 2017 6:52 AM, Sverker Eriksson <sverker.eriksson@REDACTED> wrote:



enif_send docs says:

"The message environment msg_env with all its terms (including msg)
is invalidated by a successful call to enif_send. The environment is to
either be freed with enif_free_env of cleared for reuse with 
enif_clear_env."

which means you have to call enif_clear_env before reusing msg_env
in the second call to enif_send.

Or if you're running OTP 19 you can pass msg_env as NULL,
in which case the message term is copied and its environment left intact
by enif_send.


/Sverker, Erlang/OTP



On 03/21/2017 05:10 AM, Vans S wrote:
> I am having a weird issue with enif_send.
>
> What is happening is I am interoping with a 3rd party C library which has
> its own event loop and procs callbacks from its own thread.
>
> When the callback procs (in the C NIF) I want to call enif_send to get
> the message back to an erlang pid.
>
> When I call enif_send the first term I pass it works, then every subsequent message
> gets dropped unless its exactly the same as the first time passed.
>
> For example
>
>
> static ErlNifPid my_temp_pid;
> static void on_callback(void* user_data)
> {
> ErlNifEnv* msg_env = enif_alloc_env();
> enif_send(NULL, &my_temp_pid, msg_env, mk_atom(msg_env, "okk"));
> enif_send(NULL, &my_temp_pid, msg_env, mk_atom(msg_env, "aaokk"));
> enif_free_env(msg_env);}
>
> *on_callback proced
> 6> receive X-> X after 1 -> none end.
> okk
>
> 7> receive X-> X after 1 -> none end.none
> *on_callback proced
> 8> receive X-> X after 1 -> none end.
> okk
> 9> receive X-> X after 1 -> none end.
> none
> *on_callback proced
> *on_callback proced
> 10> receive X-> X after 1 -> none end.
> okk
> 11> receive X-> X after 1 -> none end.
> okk
> 12> receive X-> X after 1 -> none end.
> none
> What is the correct way to do this? Thanks.
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions
>

_______________________________________________
erlang-questions mailing list
erlang-questions@REDACTED
http://erlang.org/mailman/listinfo/erlang-questions



More information about the erlang-questions mailing list