aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/nifs/common
diff options
context:
space:
mode:
authorLukas Larsson <[email protected]>2016-05-11 11:16:16 +0200
committerRickard Green <[email protected]>2016-05-11 16:48:37 +0200
commit3471d44a6a5ed5ab038c4cdc76b350119fe745e2 (patch)
tree629de2dea305b83ee00d685cffe6b8e9533eb7d7 /erts/emulator/nifs/common
parent4aea719054a594a06aceb34afca0ea3df65ead77 (diff)
downloadotp-3471d44a6a5ed5ab038c4cdc76b350119fe745e2.tar.gz
otp-3471d44a6a5ed5ab038c4cdc76b350119fe745e2.tar.bz2
otp-3471d44a6a5ed5ab038c4cdc76b350119fe745e2.zip
erts: Only allow remove from trace_status callback
Make it so that it is only possible to remove a tracer via returning remove from an erl_tracer. This limition is put in place in order to avoid a lot of lock checking and taking in various places, especially in regards to trace events happening on dirty schedulers.
Diffstat (limited to 'erts/emulator/nifs/common')
-rw-r--r--erts/emulator/nifs/common/erl_tracer_nif.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/erts/emulator/nifs/common/erl_tracer_nif.c b/erts/emulator/nifs/common/erl_tracer_nif.c
index 8a9a1bf16c..6dddc80607 100644
--- a/erts/emulator/nifs/common/erl_tracer_nif.c
+++ b/erts/emulator/nifs/common/erl_tracer_nif.c
@@ -70,6 +70,7 @@ ERL_NIF_INIT(erl_tracer, nif_funcs, load, NULL, upgrade, unload)
ATOM_DECL(strict_monotonic); \
ATOM_DECL(timestamp); \
ATOM_DECL(trace); \
+ ATOM_DECL(trace_status); \
ATOM_DECL(trace_ts); \
ATOM_DECL(true); \
ATOM_DECL(gc_minor_start); \
@@ -118,19 +119,22 @@ static ERL_NIF_TERM enabled(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
ErlNifPid to_pid;
ErlNifPort to_port;
+ ERL_NIF_TERM ret = enif_is_identical(argv[0], atom_trace_status) ?
+ atom_remove : atom_discard;
+
ASSERT(argc == 3);
if (enif_get_local_pid(env, argv[1], &to_pid)) {
if (!enif_is_process_alive(env, &to_pid))
/* tracer is dead so we should remove this trace point */
- return atom_remove;
+ return ret;
} else if (enif_get_local_port(env, argv[1], &to_port)) {
if (!enif_is_port_alive(env, &to_port))
/* tracer is dead so we should remove this trace point */
- return atom_remove;
+ return ret;
} else {
/* The state was not a pid or a port */
- return atom_remove;
+ return ret;
}
/* Only generate trace for when tracer != tracee */