aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/erl_nif.c
diff options
context:
space:
mode:
authorRickard Green <[email protected]>2017-06-09 12:09:18 +0200
committerGitHub <[email protected]>2017-06-09 12:09:18 +0200
commit90ea65301d65e95ea3932fe6a49c3e859a1d28ae (patch)
tree5764625fcce53d371ea7d3f6c1254a02a45c7e71 /erts/emulator/beam/erl_nif.c
parent4b258844c4c0a9102d95cb03d7e1c4e58e147987 (diff)
parente606eae1325a9f73140ab309d5dbbb7cdb589a04 (diff)
downloadotp-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.c58
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;