aboutsummaryrefslogtreecommitdiffstats
path: root/erts
diff options
context:
space:
mode:
Diffstat (limited to 'erts')
-rw-r--r--erts/doc/src/erlang.xml2
-rw-r--r--erts/doc/src/match_spec.xml52
-rw-r--r--erts/emulator/beam/erl_trace.c4
-rw-r--r--erts/emulator/beam/register.c37
-rw-r--r--erts/emulator/drivers/win32/win_efile.c3
-rw-r--r--erts/emulator/test/binary_SUITE.erl10
6 files changed, 85 insertions, 23 deletions
diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml
index e683f161f1..c3c0dd77d7 100644
--- a/erts/doc/src/erlang.xml
+++ b/erts/doc/src/erlang.xml
@@ -407,7 +407,7 @@ iolist() = [char() | binary() | iolist()]
</desc>
</func>
<func>
- <name>erlang:binary_to_term(Binary, Opts) -> term()</name>
+ <name>binary_to_term(Binary, Opts) -> term()</name>
<fsummary>Decode an Erlang external term format binary</fsummary>
<type>
<v>Opts = [safe]</v>
diff --git a/erts/doc/src/match_spec.xml b/erts/doc/src/match_spec.xml
index d6492198ca..f0390c9db8 100644
--- a/erts/doc/src/match_spec.xml
+++ b/erts/doc/src/match_spec.xml
@@ -60,7 +60,7 @@
<section>
<title>Grammar</title>
- <p>A match_spec can be described in this <em>informal</em> grammar:</p>
+ <p>A match_spec used in tracing can be described in this <em>informal</em> grammar:</p>
<list type="bulleted">
<item>MatchExpression ::= [ MatchFunction, ... ]
</item>
@@ -117,6 +117,52 @@
<c><![CDATA[display]]></c> | <c><![CDATA[caller]]></c> | <c><![CDATA[set_tcw]]></c> |
<c><![CDATA[silent]]></c></item>
</list>
+
+ <p>A match_spec used in ets can be described in this <em>informal</em> grammar:</p>
+ <list type="bulleted">
+ <item>MatchExpression ::= [ MatchFunction, ... ]
+ </item>
+ <item>MatchFunction ::= { MatchHead, MatchConditions, MatchBody }
+ </item>
+ <item>MatchHead ::= MatchVariable | <c><![CDATA['_']]></c> | { MatchHeadPart, ... }
+ </item>
+ <item>MatchHeadPart ::= term() | MatchVariable | <c><![CDATA['_']]></c></item>
+ <item>MatchVariable ::= '$&lt;number&gt;'
+ </item>
+ <item>MatchConditions ::= [ MatchCondition, ...] | <c><![CDATA[[]]]></c></item>
+ <item>MatchCondition ::= { GuardFunction } |
+ { GuardFunction, ConditionExpression, ... }
+ </item>
+ <item>BoolFunction ::= <c><![CDATA[is_atom]]></c> | <c><![CDATA[is_constant]]></c> |
+ <c><![CDATA[is_float]]></c> | <c><![CDATA[is_integer]]></c> | <c><![CDATA[is_list]]></c> |
+ <c><![CDATA[is_number]]></c> | <c><![CDATA[is_pid]]></c> | <c><![CDATA[is_port]]></c> |
+ <c><![CDATA[is_reference]]></c> | <c><![CDATA[is_tuple]]></c> | <c><![CDATA[is_binary]]></c> |
+ <c><![CDATA[is_function]]></c> | <c><![CDATA[is_record]]></c> | <c><![CDATA[is_seq_trace]]></c> |
+ <c><![CDATA['and']]></c> | <c><![CDATA['or']]></c> | <c><![CDATA['not']]></c> | <c><![CDATA['xor']]></c> |
+ <c><![CDATA[andalso]]></c> | <c><![CDATA[orelse]]></c></item>
+ <item>ConditionExpression ::= ExprMatchVariable | { GuardFunction } |
+ { GuardFunction, ConditionExpression, ... } | TermConstruct
+ </item>
+ <item>ExprMatchVariable ::= MatchVariable (bound in the MatchHead) |
+ <c><![CDATA['$_']]></c> | <c><![CDATA['$$']]></c></item>
+ <item>TermConstruct = {{}} | {{ ConditionExpression, ... }} |
+ <c><![CDATA[[]]]></c> | [ConditionExpression, ...] | NonCompositeTerm | Constant
+ </item>
+ <item>NonCompositeTerm ::= term() (not list or tuple)
+ </item>
+ <item>Constant ::= {<c><![CDATA[const]]></c>, term()}
+ </item>
+ <item>GuardFunction ::= BoolFunction | <c><![CDATA[abs]]></c> |
+ <c><![CDATA[element]]></c> | <c><![CDATA[hd]]></c> | <c><![CDATA[length]]></c> | <c><![CDATA[node]]></c> |
+ <c><![CDATA[round]]></c> | <c><![CDATA[size]]></c> | <c><![CDATA[tl]]></c> | <c><![CDATA[trunc]]></c> |
+ <c><![CDATA['+']]></c> | <c><![CDATA['-']]></c> | <c><![CDATA['*']]></c> | <c><![CDATA['div']]></c> |
+ <c><![CDATA['rem']]></c> | <c><![CDATA['band']]></c> | <c><![CDATA['bor']]></c> | <c><![CDATA['bxor']]></c> |
+ <c><![CDATA['bnot']]></c> | <c><![CDATA['bsl']]></c> | <c><![CDATA['bsr']]></c> | <c><![CDATA['>']]></c> |
+ <c><![CDATA['>=']]></c> | <c><![CDATA['<']]></c> | <c><![CDATA['=<']]></c> | <c><![CDATA['=:=']]></c> |
+ <c><![CDATA['==']]></c> | <c><![CDATA['=/=']]></c> | <c><![CDATA['/=']]></c> | <c><![CDATA[self]]></c> |
+ <c><![CDATA[get_tcw]]></c></item>
+ <item>MatchBody ::= [ ConditionExpression, ... ]</item>
+ </list>
</section>
<section>
@@ -453,8 +499,8 @@
<section>
<title>Differences between match specifications in ETS and tracing</title>
<p>ETS match specifications are there to produce a return
- value. Usually the expression contains one single
- <c><![CDATA[ActionTerm]]></c> which defines the return value without having
+ value. Usually the <c><![CDATA[MatchBody]]></c> contains one single
+ <c><![CDATA[ConditionExpression]]></c> which defines the return value without having
any side effects. Calls with side effects are not allowed in the
ETS context.</p>
<p>When tracing there is no return value to produce, the
diff --git a/erts/emulator/beam/erl_trace.c b/erts/emulator/beam/erl_trace.c
index 8addfcf5ad..381a182e39 100644
--- a/erts/emulator/beam/erl_trace.c
+++ b/erts/emulator/beam/erl_trace.c
@@ -1941,11 +1941,13 @@ trace_proc(Process *c_p, Process *t_p, Eterm what, Eterm data)
Eterm* hp;
int need;
+ ERTS_SMP_LC_ASSERT((erts_proc_lc_my_proc_locks(t_p) != 0) || erts_is_system_blocked(0));
if (is_internal_port(t_p->tracer_proc)) {
#define LOCAL_HEAP_SIZE (5+5)
DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+
hp = local_heap;
mess = TUPLE4(hp, am_trace, t_p->id, what, data);
hp += 5;
@@ -2727,6 +2729,8 @@ trace_port(Port *t_p, Eterm what, Eterm data) {
Eterm mess;
Eterm* hp;
+ ERTS_SMP_LC_ASSERT(erts_lc_is_port_locked(t_p) || erts_is_system_blocked(0));
+
if (is_internal_port(t_p->tracer_proc)) {
#define LOCAL_HEAP_SIZE (5+5)
DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
diff --git a/erts/emulator/beam/register.c b/erts/emulator/beam/register.c
index 964c10a380..900ebcbbf7 100644
--- a/erts/emulator/beam/register.c
+++ b/erts/emulator/beam/register.c
@@ -476,8 +476,9 @@ int erts_unregister_name(Process *c_p,
* on c_prt.
*/
- if (!c_p)
+ if (!c_p) {
c_p_locks = 0;
+ }
current_c_p_locks = c_p_locks;
restart:
@@ -489,9 +490,15 @@ int erts_unregister_name(Process *c_p,
if (is_non_value(name)) {
/* Unregister current process name */
ASSERT(c_p);
- if (c_p->reg)
+#ifdef ERTS_SMP
+ if (current_c_p_locks != c_p_locks) {
+ erts_smp_proc_lock(c_p, c_p_locks);
+ current_c_p_locks = c_p_locks;
+ }
+#endif
+ if (c_p->reg) {
r.name = c_p->reg->name;
- else {
+ } else {
/* Name got unregistered while main lock was released */
res = 0;
goto done;
@@ -533,24 +540,25 @@ int erts_unregister_name(Process *c_p,
}
} else if (rp->p) {
- Process* p = rp->p;
+
#ifdef ERTS_SMP
erts_proc_safelock(c_p,
current_c_p_locks,
c_p_locks,
rp->p,
- 0,
+ (c_p == rp->p) ? current_c_p_locks : 0,
ERTS_PROC_LOCK_MAIN);
current_c_p_locks = c_p_locks;
#endif
- p->reg = NULL;
+ rp->p->reg = NULL;
+ if (IS_TRACED_FL(rp->p, F_TRACE_PROCS)) {
+ trace_proc(c_p, rp->p, am_unregister, r.name);
+ }
#ifdef ERTS_SMP
- if (rp->p != c_p)
+ if (rp->p != c_p) {
erts_smp_proc_unlock(rp->p, ERTS_PROC_LOCK_MAIN);
-#endif
- if (IS_TRACED_FL(p, F_TRACE_PROCS)) {
- trace_proc(c_p, p, am_unregister, r.name);
}
+#endif
}
hash_erase(&process_reg, (void*) &r);
res = 1;
@@ -560,14 +568,17 @@ int erts_unregister_name(Process *c_p,
reg_write_unlock();
if (c_prt != port) {
- if (port)
+ if (port) {
erts_smp_port_unlock(port);
- if (c_prt)
+ }
+ if (c_prt) {
erts_smp_port_lock(c_prt);
+ }
}
#ifdef ERTS_SMP
- if (c_p && !current_c_p_locks)
+ if (c_p && !current_c_p_locks) {
erts_smp_proc_lock(c_p, c_p_locks);
+ }
#endif
return res;
}
diff --git a/erts/emulator/drivers/win32/win_efile.c b/erts/emulator/drivers/win32/win_efile.c
index d5f2b79706..24b6fb30dc 100644
--- a/erts/emulator/drivers/win32/win_efile.c
+++ b/erts/emulator/drivers/win32/win_efile.c
@@ -689,7 +689,8 @@ Sint64* pSize; /* Where to store the size of the file. */
if (flags & EFILE_MODE_APPEND) {
crFlags = OPEN_ALWAYS;
}
- fd = CreateFile(name, access, FILE_SHARE_READ | FILE_SHARE_WRITE,
+ fd = CreateFile(name, access,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL, crFlags, FILE_ATTRIBUTE_NORMAL, NULL);
/*
diff --git a/erts/emulator/test/binary_SUITE.erl b/erts/emulator/test/binary_SUITE.erl
index 7ecc31aa29..77d2579848 100644
--- a/erts/emulator/test/binary_SUITE.erl
+++ b/erts/emulator/test/binary_SUITE.erl
@@ -438,11 +438,11 @@ terms(Config) when is_list(Config) ->
ok
end,
Term = binary_to_term(Bin),
- Term = erlang:binary_to_term(Bin, [safe]),
+ Term = binary_to_term(Bin, [safe]),
Unaligned = make_unaligned_sub_binary(Bin),
Term = binary_to_term(Unaligned),
- Term = erlang:binary_to_term(Unaligned, []),
- Term = erlang:binary_to_term(Bin, [safe]),
+ Term = binary_to_term(Unaligned, []),
+ Term = binary_to_term(Bin, [safe]),
BinC = erlang:term_to_binary(Term, [compressed]),
Term = binary_to_term(BinC),
true = size(BinC) =< size(Bin),
@@ -542,7 +542,7 @@ bad_bin_to_term(BadBin) ->
{'EXIT',{badarg,_}} = (catch binary_to_term(BadBin)).
bad_bin_to_term(BadBin,Opts) ->
- {'EXIT',{badarg,_}} = (catch erlang:binary_to_term(BadBin,Opts)).
+ {'EXIT',{badarg,_}} = (catch binary_to_term(BadBin,Opts)).
safe_binary_to_term2(doc) -> "Test safety options for binary_to_term/2";
safe_binary_to_term2(Config) when is_list(Config) ->
@@ -553,7 +553,7 @@ safe_binary_to_term2(Config) when is_list(Config) ->
BadRef = <<131,114,0,3,BadHostAtom/binary,0,<<0,0,0,255>>/binary,
Empty/binary,Empty/binary>>,
?line bad_bin_to_term(BadRef, [safe]), % good ref, with a bad atom
- ?line fullsweep_after = erlang:binary_to_term(<<131,100,0,15,"fullsweep_after">>, [safe]), % should be a good atom
+ ?line fullsweep_after = binary_to_term(<<131,100,0,15,"fullsweep_after">>, [safe]), % should be a good atom
BadExtFun = <<131,113,100,0,4,98,108,117,101,100,0,4,109,111,111,110,97,3>>,
?line bad_bin_to_term(BadExtFun, [safe]),
ok.