aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/io.c
diff options
context:
space:
mode:
authorRaimo Niskanen <[email protected]>2012-03-22 11:29:28 +0100
committerRaimo Niskanen <[email protected]>2012-03-22 11:29:28 +0100
commit1e13b92d5c6543c82219610aa1336dbdf1f4dc2d (patch)
tree537e3b12c7e2c66b2b79c5bd1b6790821434ac91 /erts/emulator/beam/io.c
parentb2b96f8b37143e760cfe6638c6c4b3bd34604e1f (diff)
parent4cb0e5bc5227eaf675bb633f77e838b7297be87d (diff)
downloadotp-1e13b92d5c6543c82219610aa1336dbdf1f4dc2d.tar.gz
otp-1e13b92d5c6543c82219610aa1336dbdf1f4dc2d.tar.bz2
otp-1e13b92d5c6543c82219610aa1336dbdf1f4dc2d.zip
Merge branch 'raimo/close-ports-on-halt/OTP-9985' into maint
* raimo/close-ports-on-halt/OTP-9985: erts: Basic test of erlang:halt/0..2 erts: Document erlang:halt/2 and update erlang:halt/0,1 erts: Implement erlang:halt/2 stdlib: Stop working around erlang:halt not flushing erts: Make erlang:halt/0,1 close ports and flush async threads erts: Remove forgotten and unused function erl_exit0 erts: Implement erl_halt erts: Remove unused ntbuild.erl
Diffstat (limited to 'erts/emulator/beam/io.c')
-rw-r--r--erts/emulator/beam/io.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/erts/emulator/beam/io.c b/erts/emulator/beam/io.c
index fe1a7ba345..fb1514a147 100644
--- a/erts/emulator/beam/io.c
+++ b/erts/emulator/beam/io.c
@@ -1837,6 +1837,7 @@ terminate_port(Port *prt)
Eterm send_closed_port_id;
Eterm connected_id = NIL /* Initialize to silence compiler */;
erts_driver_t *drv;
+ int halt;
ERTS_SMP_CHK_NO_PROC_LOCKS;
ERTS_SMP_LC_ASSERT(erts_lc_is_port_locked(prt));
@@ -1844,6 +1845,8 @@ terminate_port(Port *prt)
ASSERT(!prt->nlinks);
ASSERT(!prt->monitors);
+ /* prt->status may be altered by kill_port()below */
+ halt = (prt->status & ERTS_PORT_SFLG_HALT) != 0;
if (prt->status & ERTS_PORT_SFLG_SEND_CLOSED) {
erts_port_status_band_set(prt, ~ERTS_PORT_SFLG_SEND_CLOSED);
send_closed_port_id = prt->id;
@@ -1895,6 +1898,10 @@ terminate_port(Port *prt)
* We don't want to send the closed message until after the
* port has been removed from the port table (in kill_port()).
*/
+ if (halt && (erts_smp_atomic32_dec_read_nob(&erts_halt_progress) == 0)) {
+ erts_smp_port_unlock(prt); /* We will exit and never return */
+ erl_exit_flush_async(erts_halt_code, "");
+ }
if (is_internal_port(send_closed_port_id))
deliver_result(send_closed_port_id, connected_id, am_closed);