diff options
author | Lukas Larsson <lukas@erlang-solutions.com> | 2011-11-16 16:09:32 +0100 |
---|---|---|
committer | Lukas Larsson <lukas@erlang-solutions.com> | 2011-12-01 14:10:05 +0100 |
commit | 06e77d9baa4c631bc329aa1fafb29ee55f66d906 (patch) | |
tree | 789f80ea2b36bd51fa315ddd9224dda8c645937d | |
parent | c68746bda431c5a068e6bb4a93bfe5ae77ce2d9a (diff) | |
download | otp-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.erl | 6 | ||||
-rw-r--r-- | lib/kernel/src/inet.erl | 15 |
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. |