[erlang-questions] Are binaries relocatable?
Fri Aug 29 15:02:28 CEST 2014
On 08/28/2014 03:09 PM, Hynek Vychodil wrote:
> Hi all,
> I would like to know if binaries are relocatable. If I have binary parameter
> ErlNifBinary bin;
> if (!enif_inspect_binary(env, argv, &bin))
> return enif_make_badarg(env);
> I store binary in mine own environment
> ErlNifEnv *priv_env = enif_alloc_env();
> enif_make_copy(priv_env, argv);
> Can I then rely on bin.data pointing into same memory until I free
> enif_free_env(priv_env) ?
Your bin.data is refering to the original term argv in 'env' which is
only valid until the NIF returns.
You must do enif_inspect_binary on the copy in order to get a safe
pointer that is valid until you do enif_free_env(priv_env).
> I'm asking because I would like to avoid copying
> and share data or even return it using enif_make_resource_binary to catch
> count references.
Whether a copied binary share data with its original is implementation
dependent. Today big binaries (>64 bytes) are shared
and small binaries are copied between environments.
> I have code which makes copy of binary data but when I switch to reference
> bin.data it hangs whole VM. I would like to know if I make some mistake in
> mine code and it should work or it is wrong idea at all.
There is a known bug when calling enif_make_copy after enif_inspect_binary
that can cause the binary to get reallocated and thus the bin.data
pointer to get invalid
before the NIF returns. To detect this bug, you can call
after enif_make_copy and check if bin2.data != bin.data.
This bug has been lingering as I thought it was an exotic scenario
(apparently not) and I have
been a bit unsure how to fix it without ruin performance.
More information about the erlang-questions