From 17035a025c7b6fbcdd05f0385ba42546608b4c53 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Sat, 15 Jun 2013 12:38:25 +0200 Subject: Improve solution --- erts/preloaded/ebin/prim_inet.beam | Bin 70112 -> 70520 bytes erts/preloaded/src/prim_inet.erl | 28 ++++++++++++++++++++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/erts/preloaded/ebin/prim_inet.beam b/erts/preloaded/ebin/prim_inet.beam index ef305ae1e9..8638ef677e 100644 Binary files a/erts/preloaded/ebin/prim_inet.beam and b/erts/preloaded/ebin/prim_inet.beam differ diff --git a/erts/preloaded/src/prim_inet.erl b/erts/preloaded/src/prim_inet.erl index 36a650cb5c..fb1269cf91 100644 --- a/erts/preloaded/src/prim_inet.erl +++ b/erts/preloaded/src/prim_inet.erl @@ -177,8 +177,32 @@ close_pend_loop(S, N) -> end. close_port(S) -> - catch erlang:port_close(S), - receive {'EXIT',S,_} -> ok after 0 -> ok end. + case erlang:process_info(self(), trap_exit) of + {trap_exit,true} -> + %% Ensure exit message and consume it + link(S), + %% This is still not a perfect solution. + %% + %% The problem is to close the port and consume any exit + %% message while not knowing if this process traps exit + %% nor if this process has a link to the port. Here we + %% just knows that this process traps exit. + %% + %% If we right here get killed for some reason that exit + %% signal will propagate to the port and onwards to anyone + %% that is linked to the port. E.g when we close a socket + %% that is not ours. + %% + %% The problem can be solved with lists:member on our link + %% list but we deem that as potentially too expensive. We + %% need an is_linked/1 function or guard, or we need + %% a port_close function that can atomically unlink... + catch erlang:port_close(S), + receive {'EXIT',S,_} -> ok end; + {trap_exit,false} -> + catch erlang:port_close(S), + ok + end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% -- cgit v1.2.3