diff options
author | Rickard Green <[email protected]> | 2017-06-09 12:09:18 +0200 |
---|---|---|
committer | GitHub <[email protected]> | 2017-06-09 12:09:18 +0200 |
commit | 90ea65301d65e95ea3932fe6a49c3e859a1d28ae (patch) | |
tree | 5764625fcce53d371ea7d3f6c1254a02a45c7e71 /erts/emulator/beam/erl_nif.c | |
parent | 4b258844c4c0a9102d95cb03d7e1c4e58e147987 (diff) | |
parent | e606eae1325a9f73140ab309d5dbbb7cdb589a04 (diff) | |
download | otp-90ea65301d65e95ea3932fe6a49c3e859a1d28ae.tar.gz otp-90ea65301d65e95ea3932fe6a49c3e859a1d28ae.tar.bz2 otp-90ea65301d65e95ea3932fe6a49c3e859a1d28ae.zip |
Merge pull request #1400 from tburghart/trb/erts/enif_whereis
Add enif_whereis_pid() and enif_whereis_port() functions
OTP-14453
Diffstat (limited to 'erts/emulator/beam/erl_nif.c')
-rw-r--r-- | erts/emulator/beam/erl_nif.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c index ea835d1b64..4815e5e7bb 100644 --- a/erts/emulator/beam/erl_nif.c +++ b/erts/emulator/beam/erl_nif.c @@ -879,6 +879,64 @@ enif_port_command(ErlNifEnv *env, const ErlNifPort* to_port, return res; } +/* + * env must be the caller's environment in a scheduler or NULL in a + * non-scheduler thread. + * name must be an atom - anything else will just waste time. + */ +static Eterm call_whereis(ErlNifEnv *env, Eterm name) +{ + Process *c_p; + Eterm res; + int scheduler; + int unlock; + + execution_state(env, &c_p, &scheduler); + ASSERT((c_p && scheduler) || (!c_p && !scheduler)); + + unlock = 0; + if (scheduler < 0) { + /* dirty scheduler */ + if (ERTS_PROC_IS_EXITING(c_p)) + return 0; + + if (env->proc->static_flags & ERTS_STC_FLG_SHADOW_PROC) { + erts_smp_proc_lock(c_p, ERTS_PROC_LOCK_MAIN); + unlock = 1; + } + } + res = erts_whereis_name_to_id(c_p, name); + + if (unlock) + erts_smp_proc_unlock(c_p, ERTS_PROC_LOCK_MAIN); + + return res; +} + +int enif_whereis_pid(ErlNifEnv *env, ERL_NIF_TERM name, ErlNifPid *pid) +{ + Eterm res; + + if (is_not_atom(name)) + return 0; + + res = call_whereis(env, name); + /* enif_get_local_ functions check the type */ + return enif_get_local_pid(env, res, pid); +} + +int enif_whereis_port(ErlNifEnv *env, ERL_NIF_TERM name, ErlNifPort *port) +{ + Eterm res; + + if (is_not_atom(name)) + return 0; + + res = call_whereis(env, name); + /* enif_get_local_ functions check the type */ + return enif_get_local_port(env, res, port); +} + ERL_NIF_TERM enif_make_copy(ErlNifEnv* dst_env, ERL_NIF_TERM src_term) { Uint sz; |