From 06e77d9baa4c631bc329aa1fafb29ee55f66d906 Mon Sep 17 00:00:00 2001 From: Lukas Larsson Date: Wed, 16 Nov 2011 16:09:32 +0100 Subject: 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. --- lib/kernel/src/gen_tcp.erl | 6 +++--- lib/kernel/src/inet.erl | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 3 deletions(-) (limited to 'lib/kernel') 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. -- cgit v1.2.3