From 3a10d2e251e5490c05b32ca9c18165e9d1a055d9 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Mon, 19 Mar 2012 10:49:39 +0100 Subject: erts: Make erlang:halt/0,1 close ports and flush async threads --- erts/emulator/beam/bif.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'erts/emulator/beam/bif.c') diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c index f8305944a4..148817bc7c 100644 --- a/erts/emulator/beam/bif.c +++ b/erts/emulator/beam/bif.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1996-2011. All Rights Reserved. + * Copyright Ericsson AB 1996-2012. All Rights Reserved. * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in @@ -3666,9 +3666,8 @@ BIF_RETTYPE display_nl_0(BIF_ALIST_0) BIF_RETTYPE halt_0(BIF_ALIST_0) { VERBOSE(DEBUG_SYSTEM,("System halted by BIF halt/0\n")); - erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN); - erl_exit(0, ""); - return NIL; /* Pedantic (lint does not know about erl_exit) */ + erl_halt(0); + ERTS_BIF_YIELD1(bif_export[BIF_halt_1], BIF_P, am_undefined); } /**********************************************************************/ @@ -3685,12 +3684,12 @@ BIF_RETTYPE halt_1(BIF_ALIST_1) if (is_small(BIF_ARG_1) && (code = signed_val(BIF_ARG_1)) >= 0) { VERBOSE(DEBUG_SYSTEM,("System halted by BIF halt(%d)\n", code)); - erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN); - erl_exit(-code, ""); - } else if (is_string(BIF_ARG_1) || BIF_ARG_1 == NIL) { - if ((i = intlist_to_buf(BIF_ARG_1, msg, MSG_SIZE-1)) < 0) { + erl_halt((int)(- code)); + ERTS_BIF_YIELD1(bif_export[BIF_halt_1], BIF_P, am_undefined); + } + else if (is_string(BIF_ARG_1) || BIF_ARG_1 == NIL) { + if ((i = intlist_to_buf(BIF_ARG_1, halt_msg, HALT_MSG_SIZE-1)) < 0) goto error; - } msg[i] = '\0'; VERBOSE(DEBUG_SYSTEM,("System halted by BIF halt(%s)\n", msg)); erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN); -- cgit v1.2.3 From b80ee2bbf4c2c28ceeb3e561fddc9020c686071f Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Mon, 19 Mar 2012 10:55:31 +0100 Subject: erts: Implement erlang:halt/2 --- erts/emulator/beam/bif.c | 102 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 91 insertions(+), 11 deletions(-) (limited to 'erts/emulator/beam/bif.c') diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c index 148817bc7c..ebdca87f4a 100644 --- a/erts/emulator/beam/bif.c +++ b/erts/emulator/beam/bif.c @@ -3665,42 +3665,122 @@ BIF_RETTYPE display_nl_0(BIF_ALIST_0) /* ARGSUSED */ BIF_RETTYPE halt_0(BIF_ALIST_0) { - VERBOSE(DEBUG_SYSTEM,("System halted by BIF halt/0\n")); + VERBOSE(DEBUG_SYSTEM,("System halted by BIF halt()\n")); erl_halt(0); ERTS_BIF_YIELD1(bif_export[BIF_halt_1], BIF_P, am_undefined); } /**********************************************************************/ -#define MSG_SIZE 200 +#define HALT_MSG_SIZE 200 +static char halt_msg[HALT_MSG_SIZE]; /* stop the system with exit code */ /* ARGSUSED */ BIF_RETTYPE halt_1(BIF_ALIST_1) { Sint code; - static char msg[MSG_SIZE]; - int i; if (is_small(BIF_ARG_1) && (code = signed_val(BIF_ARG_1)) >= 0) { - VERBOSE(DEBUG_SYSTEM,("System halted by BIF halt(%d)\n", code)); + VERBOSE(DEBUG_SYSTEM,("System halted by BIF halt(%T)\n", BIF_ARG_1)); erl_halt((int)(- code)); ERTS_BIF_YIELD1(bif_export[BIF_halt_1], BIF_P, am_undefined); } + else if (ERTS_IS_ATOM_STR("abort", BIF_ARG_1)) { + VERBOSE(DEBUG_SYSTEM,("System halted by BIF halt(%T)\n", BIF_ARG_1)); + erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN); + erl_exit(ERTS_ABORT_EXIT, ""); + } else if (is_string(BIF_ARG_1) || BIF_ARG_1 == NIL) { - if ((i = intlist_to_buf(BIF_ARG_1, halt_msg, HALT_MSG_SIZE-1)) < 0) + int i; + + if ((i = intlist_to_buf(BIF_ARG_1, halt_msg, HALT_MSG_SIZE-1)) < 0) { goto error; - msg[i] = '\0'; - VERBOSE(DEBUG_SYSTEM,("System halted by BIF halt(%s)\n", msg)); + } + halt_msg[i] = '\0'; + VERBOSE(DEBUG_SYSTEM,("System halted by BIF halt(%T)\n", BIF_ARG_1)); erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN); - erl_exit(ERTS_DUMP_EXIT, "%s\n", msg); - } else { - error: + erl_exit(ERTS_DUMP_EXIT, "%s\n", halt_msg); + } + else + goto error; + return NIL; /* Pedantic (lint does not know about erl_exit) */ + error: BIF_ERROR(BIF_P, BADARG); +} + +/**********************************************************************/ + +/* stop the system with exit code and flags */ +/* ARGSUSED */ +BIF_RETTYPE halt_2(BIF_ALIST_2) +{ + Sint code; + Eterm optlist = BIF_ARG_2; + int flush = 0; + + for (optlist = BIF_ARG_2; + is_list(optlist); + optlist = CDR(list_val(optlist))) { + Eterm *tp, opt = CAR(list_val(optlist)); + if (is_not_tuple(opt)) + goto error; + tp = tuple_val(opt); + if (tp[0] != make_arityval(2)) + goto error; + if (tp[1] == am_flush) { + if (tp[2] == am_true) + flush = 1; + else if (tp[2] == am_false) + flush = 0; + else + goto error; + } + else + goto error; } + if (is_not_nil(optlist)) + goto error; + + if (is_small(BIF_ARG_1) && (code = signed_val(BIF_ARG_1)) >= 0) { + VERBOSE(DEBUG_SYSTEM, + ("System halted by BIF halt(%T, %T)\n", BIF_ARG_1, BIF_ARG_2)); + if (flush) { + erl_halt((int)(- code)); + ERTS_BIF_YIELD1(bif_export[BIF_halt_1], BIF_P, am_undefined); + } + else { + erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN); + erl_exit((int)(- code), ""); + } + } + else if (ERTS_IS_ATOM_STR("abort", BIF_ARG_1)) { + VERBOSE(DEBUG_SYSTEM, + ("System halted by BIF halt(%T, %T)\n", BIF_ARG_1, BIF_ARG_2)); + erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN); + erl_exit(ERTS_ABORT_EXIT, ""); + } + else if (is_string(BIF_ARG_1) || BIF_ARG_1 == NIL) { + int i; + + if ((i = intlist_to_buf(BIF_ARG_1, halt_msg, HALT_MSG_SIZE-1)) < 0) { + goto error; + } + halt_msg[i] = '\0'; + VERBOSE(DEBUG_SYSTEM, + ("System halted by BIF halt(%T, %T)\n", BIF_ARG_1, BIF_ARG_2)); + erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN); + erl_exit(ERTS_DUMP_EXIT, "%s\n", halt_msg); + } + else + goto error; return NIL; /* Pedantic (lint does not know about erl_exit) */ + error: + BIF_ERROR(BIF_P, BADARG); } +/**********************************************************************/ + BIF_RETTYPE function_exported_3(BIF_ALIST_3) { if (is_not_atom(BIF_ARG_1) || -- cgit v1.2.3