Amin
Amin

Reputation: 755

Erlang, Is it possible to reload or upgrade a nif library without restart the shell?

I have a nif library and every time i recompile it, I must restart the shell to reload or upgrade this library.

Here is my erlang code:

-module(q4).
-export([init/0]).

-on_load(init/0).


init() ->
    erlang:load_nif("./q4_nif", reload).

Every time i compile the erlang module, this error occurs:

`The on_load function for module q4 returned {error,
                                         {upgrade,
                                          "Upgrade not supported by this NIF library."}}`

and when i call init/0 function, this error occurs: {error,{reload,"Reload not supported by this NIF library."}}

Is there anyway to fix this problem and load new nif library without restarting the shell?

Upvotes: 7

Views: 1754

Answers (2)

user246672
user246672

Reputation:

UPDATE Root cause found

It appears delete must called twice before hot-reloading NIFs. This seems like a erlang bug.

force_upgrade_module(Mod) ->
  true == code:purge(Mod),
  true == code:delete(Mod),
  code:purge(Mod),
  code:delete(Mod),
  {module,Mod} == code:load(Mod).

Even with implementing upgrade in ERL_NIF_INIT, there are still some issues that may or may not be platform-specific. For example, on macOS: feel free to delete the priv/{{module}}.so after calling load_nif in the erlang stub module and it will just continue silently succeed and not really reload the NIF .so.

Upvotes: 2

Steve Vinoski
Steve Vinoski

Reputation: 20004

As the error message indicates, you need to provide an upgrade function in your NIF, which you specify in your call to ERL_NIF_INIT:

ERL_NIF_INIT(MODULE, ErlNifFunc funcs[], load, reload, upgrade, unload)

The upgrade function is documented in the erl_nif man page.

Upvotes: 6

Related Questions