[erlang-questions] weak resource reference possible in nif ?
Skype Xu
skypexu@REDACTED
Wed Nov 8 10:32:43 CET 2017
Hi,
Suppose a nif module is multi-threaded, we keep a pointer to a resource
in the
module's internal list, when the resource is no longer used by erlang
process,
erlang vm calls the resource's destructor, and we remove the pointer from
internal list in the destructor, that's fine.
However a problem arises when the internal list is also used by another
thread
created in the nif module, when some external events were triggered, the
thread
tries to use the resource pointer and sends it to a process in the vm,
problem
is there's a race condition between destructor and the internal thread,
in the destructor we try to remove it from the internal list, at the
time, the
resource's reference count is already zero, and before the destructor is
called,
the internal thread sent the resource to a proecess, by calling
enif_make_resource() to increase the count to 1, but anyway after the
destructor returned, the vm will recycle the memory of the resource
despites
the reference count is 1 again, this leads to corrupted memory.
We can not keep a resource by adding extra reference count in nif module,
if we do, the resource's destructor will never be called even if not any
erlang
process is using the resource, because the reference count will never to
dropped to 0.
It would be perfect if we can keep a weak reference in nif like the one in
C++ does, one can use weak_ptr to get back a shared_ptr object if the
object
is still using, otherwise a null pointer is returned. if this is
implemented, we
can queue a notification to the internal thread and the thread will remove
any data related to the resource. enif_monitor_process() is not a solution
because we want vm to recycle the resource when it is not used, not after
a process crashed or exited.
More information about the erlang-questions
mailing list