diff options
Diffstat (limited to 'erts')
-rw-r--r-- | erts/doc/src/notes.xml | 30 | ||||
-rw-r--r-- | erts/emulator/beam/dist.c | 23 | ||||
-rw-r--r-- | erts/emulator/beam/dist.h | 2 | ||||
-rw-r--r-- | erts/emulator/beam/erl_node_tables.c | 83 | ||||
-rw-r--r-- | erts/emulator/sys/unix/erl_child_setup.c | 11 | ||||
-rw-r--r-- | erts/vsn.mk | 2 |
6 files changed, 99 insertions, 52 deletions
diff --git a/erts/doc/src/notes.xml b/erts/doc/src/notes.xml index 42d883f269..2d396236cf 100644 --- a/erts/doc/src/notes.xml +++ b/erts/doc/src/notes.xml @@ -31,6 +31,36 @@ </header> <p>This document describes the changes made to the ERTS application.</p> +<section><title>Erts 10.0.8</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + As of ERTS version 10.0 (OTP 21.0) the + <c>erl_child_setup</c> program, which creates port + programs, ignores <c>TERM</c> signals. This setting was + unintentionally inherited by port programs. Handling of + <c>TERM</c> signals in port programs has now been + restored to the default behavior. That is, terminate the + process.</p> + <p> + Own Id: OTP-15289 Aux Id: ERIERL-235, OTP-14943, ERL-576 </p> + </item> + <item> + <p> + The fix made for OTP-15279 in erts-10.07 (OTP-21.0.8) was + not complete. It could cause a new connection attempt to + be incorrectly aborted in certain cases. This fix will + amend that flaw.</p> + <p> + Own Id: OTP-15296 Aux Id: OTP-15279, ERIERL-226 </p> + </item> + </list> + </section> + +</section> + <section><title>Erts 10.0.7</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/erts/emulator/beam/dist.c b/erts/emulator/beam/dist.c index e7c0ee65dc..1dcda29af9 100644 --- a/erts/emulator/beam/dist.c +++ b/erts/emulator/beam/dist.c @@ -3556,20 +3556,18 @@ BIF_RETTYPE erts_internal_new_connection_1(BIF_ALIST_1) BIF_RET(TUPLE2(hp, make_small(conn_id), dhandle)); } -static Sint abort_connection(DistEntry* dep, Uint32 conn_id) +Sint erts_abort_connection_rwunlock(DistEntry* dep) { - erts_de_rwlock(dep); + Sint reds = 0; + ERTS_LC_ASSERT(erts_lc_is_de_rwlocked(dep)); - if (dep->connection_id != conn_id) - ; - else if (dep->state == ERTS_DE_STATE_CONNECTED) { + if (dep->state == ERTS_DE_STATE_CONNECTED) { kill_connection(dep); } else if (dep->state == ERTS_DE_STATE_PENDING) { ErtsAtomCache *cache; ErtsDistOutputBuf *obuf; ErtsProcList *resume_procs; - Sint reds = 0; ErtsMonLnkDist *mld; ASSERT(is_nil(dep->cid)); @@ -3614,17 +3612,18 @@ static Sint abort_connection(DistEntry* dep, Uint32 conn_id) erts_de_rwlock(dep); ASSERT(dep->state == ERTS_DE_STATE_EXITING); dep->state = ERTS_DE_STATE_IDLE; - erts_de_rwunlock(dep); - return reds; } erts_de_rwunlock(dep); - return 0; + return reds; } -Sint -erts_abort_connection(DistEntry *dep, Uint32 conn_id) +static Sint abort_connection(DistEntry *dep, Uint32 conn_id) { - return abort_connection(dep, conn_id); + erts_de_rwlock(dep); + if (dep->connection_id == conn_id) + return erts_abort_connection_rwunlock(dep); + erts_de_rwunlock(dep); + return 0; } BIF_RETTYPE erts_internal_abort_connection_2(BIF_ALIST_2) diff --git a/erts/emulator/beam/dist.h b/erts/emulator/beam/dist.h index c8d0407456..e55daa7615 100644 --- a/erts/emulator/beam/dist.h +++ b/erts/emulator/beam/dist.h @@ -400,7 +400,7 @@ extern void erts_kill_dist_connection(DistEntry *dep, Uint32); extern Uint erts_dist_cache_size(void); -extern Sint erts_abort_connection(DistEntry *dep, Uint32 conn_id); +extern Sint erts_abort_connection_rwunlock(DistEntry *dep); #endif diff --git a/erts/emulator/beam/erl_node_tables.c b/erts/emulator/beam/erl_node_tables.c index 9b34af1480..f4a36d124a 100644 --- a/erts/emulator/beam/erl_node_tables.c +++ b/erts/emulator/beam/erl_node_tables.c @@ -60,6 +60,10 @@ static int references_atoms_need_init = 1; static ErtsMonotonicTime orig_node_tab_delete_delay; static ErtsMonotonicTime node_tab_delete_delay; + +static void report_gc_active_dist_entry(Eterm sysname, enum dist_entry_state); + + /* -- The distribution table ---------------------------------------------- */ #define ErtsBin2DistEntry(B) \ @@ -412,44 +416,6 @@ static void schedule_delete_dist_entry(DistEntry* dep) static void start_timer_delete_dist_entry(void *vdep) { - DistEntry *dep = vdep; - Eterm sysname; - enum dist_entry_state state; - Uint32 connection_id; - - erts_de_rlock(dep); - state = dep->state; - connection_id = dep->connection_id; - sysname = dep->sysname; - erts_de_runlock(dep); - - if (state != ERTS_DE_STATE_IDLE) { - char *state_str; - erts_dsprintf_buf_t *dsbuf = erts_create_logger_dsbuf(); - switch (state) { - case ERTS_DE_STATE_CONNECTED: - state_str = "connected"; - break; - case ERTS_DE_STATE_PENDING: - state_str = "pending connect"; - break; - case ERTS_DE_STATE_EXITING: - state_str = "exiting"; - break; - case ERTS_DE_STATE_IDLE: - state_str = "idle"; - break; - default: - state_str = "unknown"; - break; - } - erts_dsprintf(dsbuf, "Garbage collecting distribution " - "entry for node %T in state: %s", - sysname, state_str); - erts_send_error_to_logger_nogl(dsbuf); - erts_abort_connection(dep, connection_id); - } - if (node_tab_delete_delay == 0) { prepare_try_delete_dist_entry(vdep); } @@ -489,6 +455,19 @@ static void try_delete_dist_entry(DistEntry* dep) { erts_aint_t refc; + erts_de_rwlock(dep); + if (dep->state != ERTS_DE_STATE_IDLE && de_refc_read(dep,0) == 0) { + Eterm sysname = dep->sysname; + enum dist_entry_state state = dep->state; + + if (dep->state != ERTS_DE_STATE_PENDING) + ERTS_INTERNAL_ERROR("Garbage collecting connected distribution entry"); + erts_abort_connection_rwunlock(dep); + report_gc_active_dist_entry(sysname, state); + } + else + erts_de_rwunlock(dep); + erts_rwmtx_rwlock(&erts_dist_table_rwmtx); /* * Another thread might have looked up this dist entry after @@ -515,6 +494,34 @@ static void try_delete_dist_entry(DistEntry* dep) } } +static void report_gc_active_dist_entry(Eterm sysname, + enum dist_entry_state state) +{ + char *state_str; + erts_dsprintf_buf_t *dsbuf = erts_create_logger_dsbuf(); + switch (state) { + case ERTS_DE_STATE_CONNECTED: + state_str = "connected"; + break; + case ERTS_DE_STATE_PENDING: + state_str = "pending connect"; + break; + case ERTS_DE_STATE_EXITING: + state_str = "exiting"; + break; + case ERTS_DE_STATE_IDLE: + state_str = "idle"; + break; + default: + state_str = "unknown"; + break; + } + erts_dsprintf(dsbuf, "Garbage collecting distribution " + "entry for node %T in state: %s", + sysname, state_str); + erts_send_error_to_logger_nogl(dsbuf); +} + int erts_dist_entry_destructor(Binary *bin) { DistEntry *dep = ErtsBin2DistEntry(bin); diff --git a/erts/emulator/sys/unix/erl_child_setup.c b/erts/emulator/sys/unix/erl_child_setup.c index 221ee2a69d..129861ebd5 100644 --- a/erts/emulator/sys/unix/erl_child_setup.c +++ b/erts/emulator/sys/unix/erl_child_setup.c @@ -133,6 +133,7 @@ static int sigchld_pipe[2]; static int start_new_child(int pipes[]) { + struct sigaction sa; int errln = -1; int size, res, i, pos = 0; char *buff, *o_buff; @@ -143,6 +144,16 @@ start_new_child(int pipes[]) /* only child executes here */ + /* Restore default handling of sigterm... */ + sa.sa_handler = SIG_DFL; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + + if (sigaction(SIGTERM, &sa, 0) == -1) { + perror(NULL); + exit(1); + } + do { res = read(pipes[0], (char*)&size, sizeof(size)); } while(res < 0 && (errno == EINTR || errno == ERRNO_BLOCK)); diff --git a/erts/vsn.mk b/erts/vsn.mk index 293b555b18..e28716c37f 100644 --- a/erts/vsn.mk +++ b/erts/vsn.mk @@ -18,7 +18,7 @@ # %CopyrightEnd% # -VSN = 10.0.7 +VSN = 10.0.8 # Port number 4365 in 4.2 # Port number 4366 in 4.3 |