Closed OTP-Maintainer closed 3 years ago
sverker
said:
Hi
As you said, the attached test code is faulty, as it reuses an old resource type handle without calling enif_open_resource_type in upgrade().
It's perfectly ok to *not* call enif_open_resource_type in upgrade(), if the upgraded module does not need the resource type to identify existing resource objects.
The current solution is to postpone unloading of a NIF library until all existing resource objects, of all its abandoned resource types with destructors, have been garbage collected. That is, a NIF library will not be unloaded until we know all calls to its destructor functions have been done. You should able to observe this as the unload() callback is also postponed until the library is actually closed.
If this is really true:
"Even if I completely destroy the old module, so that unload is called, these stale resources persist until a garbage collection."
...that would indicate a bug as unload() should not be called until all "stale resources" with destructors
have been garbage collected. Some test code to reproduce that would be neat.
/Sverker, Erlang/OTP
bucko909
said:
Yep, it looks as though you're correct. Even if I force a new copy of the nif library with a new filename, the old dtor is called correctly on the old resources. I swear I /did/ produce the effect above, but I can't do it now, so I was probably just imagining it or using a stale resource handle to make a new resource.
It'd be great if creating invalid resources in this way caused an error, but I suppose my example code was reading from an invalid memory address anyway when it used the stale handle, so there's not much that can be done.
Original reporter:
bucko909
Affected version:OTP-18.1
Component:erts
Migrated from: https://bugs.erlang.org/browse/ERL-70