diff options
author | Lukas Larsson <[email protected]> | 2011-11-16 16:09:32 +0100 |
---|---|---|
committer | Lukas Larsson <[email protected]> | 2011-12-01 14:10:05 +0100 |
commit | 06e77d9baa4c631bc329aa1fafb29ee55f66d906 (patch) | |
tree | 789f80ea2b36bd51fa315ddd9224dda8c645937d /lib/kernel | |
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.
Diffstat (limited to 'lib/kernel')
-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. |