aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrik Nyblom <[email protected]>2010-06-01 09:55:55 +0200
committerPatrik Nyblom <[email protected]>2010-06-01 12:28:13 +0200
commitd6ed3417f87612b7a7c08e979d180e1d865482ba (patch)
tree23af3dc65c3cd72637212407d614b42cd3b1e551
parent3d783a44dc3d13830766cacf3c315c13558d69bb (diff)
downloadotp-d6ed3417f87612b7a7c08e979d180e1d865482ba.tar.gz
otp-d6ed3417f87612b7a7c08e979d180e1d865482ba.tar.bz2
otp-d6ed3417f87612b7a7c08e979d180e1d865482ba.zip
Add possibly missing process lock before unregistering oneself
-rw-r--r--erts/emulator/beam/register.c30
1 files changed, 20 insertions, 10 deletions
diff --git a/erts/emulator/beam/register.c b/erts/emulator/beam/register.c
index 1da8f768e7..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,6 +490,12 @@ int erts_unregister_name(Process *c_p,
if (is_non_value(name)) {
/* Unregister current process name */
ASSERT(c_p);
+#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 {
@@ -533,24 +540,24 @@ 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;
- if (IS_TRACED_FL(p, F_TRACE_PROCS)) {
- trace_proc(c_p, p, am_unregister, r.name);
+ 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
}
hash_erase(&process_reg, (void*) &r);
@@ -561,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;
}