aboutsummaryrefslogtreecommitdiffstats
path: root/erts
diff options
context:
space:
mode:
authorRaimo Niskanen <[email protected]>2013-05-27 10:13:24 +0200
committerRaimo Niskanen <[email protected]>2013-05-27 10:13:24 +0200
commit58de241d5d8e4b0536389b317ecc6e7a2a570997 (patch)
tree803134c892ee25d56a95fcf91a216b9f6e555ed3 /erts
parent429e9d8ce78f7498e06e252e487c75cea6c585d4 (diff)
parentcbb1f02292b2248db63a732f68cddb3b34e3c274 (diff)
downloadotp-58de241d5d8e4b0536389b317ecc6e7a2a570997.tar.gz
otp-58de241d5d8e4b0536389b317ecc6e7a2a570997.tar.bz2
otp-58de241d5d8e4b0536389b317ecc6e7a2a570997.zip
Merge branch 'raimo/race-in-prim_inet-close/OTP-10497' into maint
* raimo/race-in-prim_inet-close/OTP-10497: Do not unlink before closing port
Diffstat (limited to 'erts')
-rw-r--r--erts/preloaded/ebin/prim_inet.beambin70072 -> 70216 bytes
-rw-r--r--erts/preloaded/src/prim_inet.erl23
2 files changed, 14 insertions, 9 deletions
diff --git a/erts/preloaded/ebin/prim_inet.beam b/erts/preloaded/ebin/prim_inet.beam
index 43cbc17dbf..a0a4314128 100644
--- a/erts/preloaded/ebin/prim_inet.beam
+++ b/erts/preloaded/ebin/prim_inet.beam
Binary files differ
diff --git a/erts/preloaded/src/prim_inet.erl b/erts/preloaded/src/prim_inet.erl
index d0e70aa95c..36a650cb5c 100644
--- a/erts/preloaded/src/prim_inet.erl
+++ b/erts/preloaded/src/prim_inet.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2013. 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
@@ -151,30 +151,35 @@ shutdown_pend_loop(S, N0) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
close(S) when is_port(S) ->
- unlink(S), %% avoid getting {'EXIT', S, Reason}
case subscribe(S, [subs_empty_out_q]) of
{ok, [{subs_empty_out_q,N}]} when N > 0 ->
close_pend_loop(S, N); %% wait for pending output to be sent
_ ->
- catch erlang:port_close(S),
- ok
+ close_port(S)
end.
close_pend_loop(S, N) ->
receive
{empty_out_q,S} ->
- catch erlang:port_close(S), ok
+ close_port(S)
after ?INET_CLOSE_TIMEOUT ->
case getstat(S, [send_pend]) of
{ok, [{send_pend,N1}]} ->
- if N1 =:= N -> catch erlang:port_close(S), ok;
- true -> close_pend_loop(S, N1)
+ if
+ N1 =:= N ->
+ close_port(S);
+ true ->
+ close_pend_loop(S, N1)
end;
_ ->
- catch erlang:port_close(S), ok
+ close_port(S)
end
end.
-
+
+close_port(S) ->
+ catch erlang:port_close(S),
+ receive {'EXIT',S,_} -> ok after 0 -> ok end.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% BIND(insock(), IP, Port) -> {ok, integer()} | {error, Reason}