diff options
author | Raimo Niskanen <[email protected]> | 2013-06-15 13:57:46 +0200 |
---|---|---|
committer | Raimo Niskanen <[email protected]> | 2013-06-15 13:57:46 +0200 |
commit | c7fed1781bec1fbc893931a4d732a38a55f9ceea (patch) | |
tree | ce8c8f339d9ee29175345e59e750aa28f6582378 /erts | |
parent | bda0f0b1a0b990b095fc46c3a5c7085f69f08480 (diff) | |
parent | 17035a025c7b6fbcdd05f0385ba42546608b4c53 (diff) | |
download | otp-c7fed1781bec1fbc893931a4d732a38a55f9ceea.tar.gz otp-c7fed1781bec1fbc893931a4d732a38a55f9ceea.tar.bz2 otp-c7fed1781bec1fbc893931a4d732a38a55f9ceea.zip |
Merge branch 'raimo/race-in-prim_inet-close/OTP-10497' into maint
* raimo/race-in-prim_inet-close/OTP-10497:
Improve solution
Diffstat (limited to 'erts')
-rw-r--r-- | erts/preloaded/ebin/prim_inet.beam | bin | 70112 -> 70520 bytes | |||
-rw-r--r-- | 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 Binary files differindex ef305ae1e9..8638ef677e 100644 --- a/erts/preloaded/ebin/prim_inet.beam +++ b/erts/preloaded/ebin/prim_inet.beam 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. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% |