Age | Commit message (Collapse) | Author |
|
#### Why do we need this new feature?
There are cases when a NIF needs to send a message, using `enif_send()`, to a long-lived process with a registered name.
A common use-case is logging, where asynchronous fire-and-forget messages are the norm.
There can also be cases where a yielding or dirty NIF or background thread may request a callback from a service with additional information it needs to complete its operation, yielding or waiting (with suitable timeouts, etc) until its state has been updated through the NIF module's API.
NIFs can only send messages to pids, and the lack of name resolution leaves a complicated dance between separate monitoring processes and the NIF as the only way to keep a NIF informed of the whereabouts of such long-lived processes.
Providing a reliable, built-in facility for NIFs to resolve process (or port) names simplifies these use cases considerably.
#### Risks or uncertain artifacts?
Testing has not exposed any significant risk.
The implementation behaves as expected on regular and dirty scheduler threads as well as non-scheduler threads.
By constraining the `enif_whereis_...()` functions to their minimal scopes and using patterns consistent with related functions, the implementation, testing, and maintenance burden is low.
The API and behavior of existing functions is unchanged.
#### How did you solve it?
While extending `enif_send()` to operate on a pid or an atom (as `erlang:send/2` does) was attractive, it would have entailed changing the type of its `to_pid` parameter and thereby breaking backward compatibility.
The same consideration applies to `enif_port_command()`.
That leaves a choice between 1, 2, or 3 new functions:
1. `enif_whereis()`
2. `enif_whereis_pid()` and `enif_whereis_port()`
3. All of the above.
While option (1), directly mimicking the behavior of `erlang:whereis/1`, is appealing, it poses potential problems if `pid()` or `port()` are subsequently implemented as non-integral types that must be bound to an owning `ErlNifEnv` instance.
Therefore, option (2) has been chosen to use `ErlNifPid`/`ErlNifPort` structures in the API to maintain proper term ownership semantics.
|
|
|
|
|
|
|
|
Allow for expanding support to 64-bit hashes without breaking the
interface.
|
|
|
|
|
|
A more generic hashing function which can also hash terms based on
`make_internal_hash'.
|
|
|
|
These allow one to hash VM terms from NIF code.
|
|
|
|
|
|
|
|
Conflicts:
erts/emulator/beam/erl_binary.h
erts/emulator/beam/erl_monitors.c
erts/emulator/beam/erl_nif.c
erts/emulator/beam/global.h
erts/emulator/test/nif_SUITE_data/nif_SUITE.c
|
|
to negative int as error and positive as success.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
* sverker/remove-nif-reload:
erts: Cuddle nif_SUITE:consume_timeslice
erts: Remove old doc note for erlang:load_nif
erts: Remove deprecated nif 'reload' feature
erts: Fix trace_nif_SUITE to load nif lib only once
|
|
Anywhere but the beam sources we shouldn't #include "erl_nif.h", because
what "erl_nif.h" does is: (1) fail to find it outside of -I dirs, (2)
then treat it as if it was written like <erl_nif.h>. Using <erl_nif.h>
skips (1).
More information can be found in 6.10.2 of the C standard.
Because the examples use "erl_nif.h", NIF projects in the Erlang
ecosystem copy this verbatim and make the same mistake.
|
|
and instead let erlang:load_nif/2 return {error, {reload, _}}
before even trying to load the library
if a NIF library has already been successfully loaded
for the calling module instance.
|
|
Fix some older errors as well.
|
|
* rickard/ds-purge-module/OTP-13808:
Perform check_process_code while process is executing dirty
Conflicts:
erts/doc/src/erl_nif.xml
|
|
|
|
|
|
|
|
This commit only changes the order of functions and does some
other rearrangements to that the diff with the next commit will
be easier to follow. No content or XML tags are changed.
|
|
|
|
|
|
|
|
|
|
|
|
* rickard/ds-doc/OTP-13123:
minor fixes
|
|
|
|
|
|
* egil/erts/nif-format_term/OTP-13580:
runtime_tools: Change erts_snprintf to enif_snprintf
erts: Document enif_snprintf
erts: Add tests for enif_snprintf
erts: Add enif_snprintf
Conflicts:
erts/emulator/beam/erl_nif_api_funcs.h
|
|
|
|
- Termination of a process...
- Modify trace flags of process...
- Process info on process...
- Register/unregister of name on process...
- Set group leader on process...
... while it is executing a dirty NIF.
|
|
|
|
Add the possibility to use modules as trace data receivers. The functions
in the module have to be nifs as otherwise complex trace probes will be
very hard to handle (complex means trace probes for ports for example).
This commit changes the way that the ptab->tracer field works from always
being an immediate, to now be NIL if no tracer is present or else be
the tuple {TracerModule, TracerState} where TracerModule is an atom that
is later used to lookup the appropriate tracer callbacks to call and
TracerState is just passed to the tracer callback. The default process and
port tracers have been rewritten to use the new API.
This commit also changes the order which trace messages are delivered to the
potential tracer process. Any enif_send done in a tracer module may be delayed
indefinitely because of lock order issues. If a message is delayed any other
trace message send from that process is also delayed so that order is preserved
for each traced entity. This means that for some trace events (i.e. send/receive)
the events may come in an unintuitive order (receive before send) to the
trace receiver. Timestamps are taken when the trace message is generated so
trace messages from differented processes may arrive with the timestamp
out of order.
Both the erlang:trace and seq_trace:set_system_tracer accept the new tracer
module tracers and also the backwards compatible arguments.
OTP-10267
|
|
* lukas/erts/enif_send_null_env/OTP-13495:
erts: Add enif_send with NULL as msg env
|
|
* henrik/update-copyrightyear:
update copyright-year
|
|
This is an optimization for reducing the number of heap fragments
allocated when sending a message where the majority of the
message payload is on the sending process' heap.
|
|
|