aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLukas Larsson <lukas@erlang-solutions.com>2011-11-16 16:09:32 +0100
committerLukas Larsson <lukas@erlang-solutions.com>2011-12-01 14:10:05 +0100
commit06e77d9baa4c631bc329aa1fafb29ee55f66d906 (patch)
tree789f80ea2b36bd51fa315ddd9224dda8c645937d
parentc68746bda431c5a068e6bb4a93bfe5ae77ce2d9a (diff)
downloadotp-06e77d9baa4c631bc329aa1fafb29ee55f66d906.tar.gz
otp-06e77d9baa4c631bc329aa1fafb29ee55f66d906.tar.bz2
otp-06e77d9baa4c631bc329aa1fafb29ee55f66d906.zip
sendfile caller now has to be the controlling_process
This is needed because otherwise there could be scenarios when the efile driver blocks a fd and then crashes without the inet driver ever finding out. Now when the process crashes the port will close and we can cleanup in the inet driver.
-rw-r--r--lib/kernel/src/gen_tcp.erl6
-rw-r--r--lib/kernel/src/inet.erl15
2 files changed, 18 insertions, 3 deletions
diff --git a/lib/kernel/src/gen_tcp.erl b/lib/kernel/src/gen_tcp.erl
index 9dd70ce5cc..2eaa44b966 100644
--- a/lib/kernel/src/gen_tcp.erl
+++ b/lib/kernel/src/gen_tcp.erl
@@ -412,16 +412,16 @@ mod([], Address) ->
sendfile(#file_descriptor{ module = Mod } = Fd, Sock, Offset, Bytes,
ChunkSize, Headers, Trailers, Nodiskio, MNowait, Sync)
when is_port(Sock) ->
- ok = prim_inet:ignorefd(Sock,true),
+ ok = inet:lock_socket(Sock,true),
{ok, SockFd} = prim_inet:getfd(Sock),
case Mod:sendfile(Fd, SockFd, Offset, Bytes, ChunkSize, Headers, Trailers,
Nodiskio, MNowait, Sync) of
{error, enotsup} ->
- ok = prim_inet:ignorefd(Sock,false),
+ ok = inet:lock_socket(Sock,false),
sendfile_fallback(Fd, Sock, Offset, Bytes, ChunkSize,
Headers, Trailers);
Else ->
- ok = prim_inet:ignorefd(Sock,false),
+ ok = inet:lock_socket(Sock,false),
Else
end;
sendfile(_,_,_,_,_,_,_,_,_,_) ->
diff --git a/lib/kernel/src/inet.erl b/lib/kernel/src/inet.erl
index b60c68e3a1..49f64a9236 100644
--- a/lib/kernel/src/inet.erl
+++ b/lib/kernel/src/inet.erl
@@ -40,6 +40,10 @@
-export([tcp_controlling_process/2, udp_controlling_process/2,
tcp_close/1, udp_close/1]).
+
+%% used by sendfile
+-export([lock_socket/2]).
+
%% used by socks5
-export([setsockname/2, setpeername/2]).
@@ -1353,3 +1357,14 @@ stop_timer(Timer) ->
end;
T -> T
end.
+
+
+lock_socket(S,Val) ->
+ case erlang:port_info(S, connected) of
+ {connected, Pid} when Pid =/= self() ->
+ {error, not_owner};
+ undefined ->
+ {error, einval};
+ _ ->
+ prim_inet:ignorefd(S,Val)
+ end.