[erlang-questions] dirty nif and enif_make_badarg()

Jesper Louis Andersen jesper.louis.andersen@REDACTED
Wed May 28 23:19:20 CEST 2014


In some of the code I've written, I opted to check for bad arguments before
scheduling the job on the dirty scheduler. This means that you don't move
the call to the dirty scheduler unless you know it will run. But I like
Steve's suggestion to check as much as possible in the Erlang VM as well.


On Wed, May 28, 2014 at 10:51 PM, Daniel Goertzen <daniel.goertzen@REDACTED
> wrote:

> Thanks, that's what I will do then.
>
> PS, the dirty schedulers are working very well for me.  I ran a cpu-bound
> nif that took about an hour, and the rest of the Erlang system just kept on
> ticking.
>
>
> On Wed, May 28, 2014 at 2:46 PM, Steve Vinoski <vinoski@REDACTED> wrote:
>
>>
>>
>>
>> On Wed, May 28, 2014 at 3:19 PM, Daniel Goertzen <
>> daniel.goertzen@REDACTED> wrote:
>>
>>> I am trying to write a dirty nif and am following the directions from
>>> http://www.erlang.org/doc/man/erl_nif.html
>>>
>>> Exceprt:
>>> "A dirty NIF may not invoke the enif_make_badarg<http://www.erlang.org/doc/man/erl_nif.html#enif_make_badarg>to raise an exception. If it wishes to return an exception, the dirty NIF
>>> should pass a regular result indicating the exception details to its
>>> finalizer, and allow the finalizer to raise the exception on its behalf."
>>>
>>> So I am doing this; here is my finalizer....
>>>
>>>
>>> // cached atoms
>>> ERL_NIF_TERM badarg;
>>>
>>> static ERL_NIF_TERM badarg_finalizer(ErlNifEnv* env, ERL_NIF_TERM term)
>>> {
>>>     if(term == badarg)
>>>         return enif_make_badarg(env);
>>>     else
>>>         return term;
>>> }
>>>
>>> ... and I end up with the exception context of the finalizer and not the
>>> nif as desired...
>>>
>>>
>>> 5> generate_rsa:generate_rsa_key(abc, 65537).
>>> entering generate_rsa_key_nif
>>>                              entering generate_rsa_key_nif_dirty
>>>                                                                 entering
>>> badarg_finalizer
>>>
>>> ** exception error: bad argument
>>>      in function  generate_rsa:generate_rsa_key_nif/2
>>>         called as
>>> generate_rsa:generate_rsa_key_nif(badarg,18446744072346624528)   *!!!
>>> should be (abc,65537)*
>>>      in call from generate_rsa:generate_rsa_key/2 (src/generate_rsa.erl,
>>> line 25)
>>>
>>>
>>> The documentation implies I can provide the "exception details", but
>>> enif_make_badarg() doesn't offer any extra parameters.  Is there some other
>>> way to set the "exception details"?
>>>
>>
>> "Exception details" here is just general, meaning whatever kinds of error
>> information you want the finalizer to return. A NIF can raise only badarg
>> via enif_make_badarg(), and there's no way for it to control any parameters
>> associated with the exception. You might instead consider wrapping the NIF
>> function with an actual Erlang function in your module, treating the NIF
>> like an internal (non-exported) function, having the finalizer return an
>> error tuple containing relevant information, and letting Erlang raise an
>> exception based on that info.
>>
>> --steve
>>
>
>
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions
>
>


-- 
J.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20140528/cdc8477d/attachment.htm>


More information about the erlang-questions mailing list