diff options
author | Lukas Larsson <[email protected]> | 2011-11-27 17:22:05 +0100 |
---|---|---|
committer | Lukas Larsson <[email protected]> | 2011-12-02 10:39:34 +0100 |
commit | 836410f5c9e092be4b77b26b3fc9f7abde0c89de (patch) | |
tree | 5f7a42db276f5bffebf1c7baedbea3ade3d73a82 /lib/kernel/src/gen_tcp.erl | |
parent | a5b3d81936ab85edb8713f29baf85307ae0b25b8 (diff) | |
download | otp-836410f5c9e092be4b77b26b3fc9f7abde0c89de.tar.gz otp-836410f5c9e092be4b77b26b3fc9f7abde0c89de.tar.bz2 otp-836410f5c9e092be4b77b26b3fc9f7abde0c89de.zip |
Move sendfile api to file module
Since sendfile could in theory be used to send to any type
of file descriptor in *nix, it is a better fit to have it
in file.
Diffstat (limited to 'lib/kernel/src/gen_tcp.erl')
-rw-r--r-- | lib/kernel/src/gen_tcp.erl | 146 |
1 files changed, 2 insertions, 144 deletions
diff --git a/lib/kernel/src/gen_tcp.erl b/lib/kernel/src/gen_tcp.erl index 78e3ab3697..4d6c7f5f1d 100644 --- a/lib/kernel/src/gen_tcp.erl +++ b/lib/kernel/src/gen_tcp.erl @@ -22,7 +22,7 @@ -export([connect/3, connect/4, listen/2, accept/1, accept/2, shutdown/2, close/1]). --export([send/2, recv/2, recv/3, unrecv/2, sendfile/2, sendfile/5]). +-export([send/2, recv/2, recv/3, unrecv/2]). -export([controlling_process/2]). -export([fdopen/2]). @@ -106,13 +106,8 @@ {tcp_module, module()} | option(). -type socket() :: port(). --type sendfile_option() :: {chunk_size, non_neg_integer()} | - {headers, Hdrs :: list(iodata())} | - {trailers, Tlrs :: list(iodata())} | - sf_nodiskio | sf_mnowait | sf_sync. --export_type([option/0, option_name/0, connect_option/0, listen_option/0, - sendfile_option/0]). +-export_type([option/0, option_name/0, connect_option/0, listen_option/0]). %% %% Connect a socket @@ -308,52 +303,6 @@ unrecv(S, Data) when is_port(S) -> Mod:unrecv(S, Data); Error -> Error - end. - -%% -%% Send data using sendfile -%% - --define(MAX_CHUNK_SIZE, (1 bsl 20)*20). %% 20 MB, has to fit in primary memory - --spec sendfile(File, Sock, Offset, Bytes, Opts) -> - {'ok', non_neg_integer()} | {'error', inet:posix() } | - {'error', not_owner} when - File :: file:fd(), - Sock :: socket(), - Offset :: non_neg_integer(), - Bytes :: non_neg_integer(), - Opts :: [sendfile_option()]. -sendfile(File, _Sock, _Offet, _Bytes, _Opts) when is_pid(File) -> - {error, badarg}; -sendfile(File, Sock, Offset, Bytes, []) -> - sendfile(File, Sock, Offset, Bytes, ?MAX_CHUNK_SIZE, [], [], - false, false, false); -sendfile(File, Sock, Offset, Bytes, Opts) -> - ChunkSize0 = proplists:get_value(chunk_size, Opts, ?MAX_CHUNK_SIZE), - ChunkSize = if ChunkSize0 > ?MAX_CHUNK_SIZE -> - ?MAX_CHUNK_SIZE; - true -> ChunkSize0 - end, - Headers = proplists:get_value(headers, Opts, []), - Trailers = proplists:get_value(trailers, Opts, []), - sendfile(File, Sock, Offset, Bytes, ChunkSize, Headers, Trailers, - lists:member(sf_nodiskio,Opts),lists:member(sf_mnowait,Opts), - lists:member(sf_sync,Opts)). - -%% sendfile/2 --spec sendfile(File, Sock) -> - {'ok', non_neg_integer()} | {'error', inet:posix() | badarg} - when File :: file:name(), - Sock :: socket(). -sendfile(File, Sock) -> - case file:open(File, [read, raw, binary]) of - {error, Reason} -> - {error, Reason}; - {ok, Fd} -> - Res = sendfile(Fd, Sock, 0, 0, []), - file:close(Fd), - Res end. %% @@ -407,94 +356,3 @@ mod([_|Opts], Address) -> mod([], Address) -> mod(Address). - -%% Internal sendfile functions -sendfile(#file_descriptor{ module = Mod } = Fd, Sock, Offset, Bytes, - ChunkSize, Headers, Trailers, Nodiskio, MNowait, Sync) - when is_port(Sock) -> - 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 = inet:lock_socket(Sock,false), - sendfile_fallback(Fd, Sock, Offset, Bytes, ChunkSize, - Headers, Trailers); - Else -> - ok = inet:lock_socket(Sock,false), - Else - end; -sendfile(_,_,_,_,_,_,_,_,_,_) -> - {error, badarg}. - -%%% -%% Sendfile Fallback -%%% -sendfile_fallback(File, Sock, Offset, Bytes, ChunkSize, - Headers, Trailers) - when Headers == []; is_integer(Headers) -> - case sendfile_fallback(File, Sock, Offset, Bytes, ChunkSize) of - {ok, BytesSent} when is_list(Trailers), - Trailers =/= [], - is_integer(Headers) -> - sendfile_send(Sock, Trailers, BytesSent+Headers); - {ok, BytesSent} when is_list(Trailers), Trailers =/= [] -> - sendfile_send(Sock, Trailers, BytesSent); - {ok, BytesSent} when is_integer(Headers) -> - {ok, BytesSent + Headers}; - Else -> - Else - end; -sendfile_fallback(File, Sock, Offset, Bytes, ChunkSize, Headers, Trailers) -> - case sendfile_send(Sock, Headers, 0) of - {ok, BytesSent} -> - sendfile_fallback(File, Sock, Offset, Bytes, ChunkSize, BytesSent, - Trailers); - Else -> - Else - end. - - -sendfile_fallback(File, Sock, Offset, Bytes, ChunkSize) -> - {ok, CurrPos} = file:position(File, {cur, 0}), - {ok, _NewPos} = file:position(File, {bof, Offset}), - Res = sendfile_fallback_int(File, Sock, Bytes, ChunkSize, 0), - file:position(File, {bof, CurrPos}), - Res. - - -sendfile_fallback_int(File, Sock, Bytes, ChunkSize, BytesSent) - when Bytes > BytesSent; Bytes == 0 -> - Size = if Bytes == 0 -> - ChunkSize; - (Bytes - BytesSent + ChunkSize) > 0 -> - Bytes - BytesSent; - true -> - ChunkSize - end, - case file:read(File, Size) of - {ok, Data} -> - case sendfile_send(Sock, Data, BytesSent) of - {ok,NewBytesSent} -> - sendfile_fallback_int( - File, Sock, Bytes, ChunkSize, - NewBytesSent); - Error -> - Error - end; - eof -> - {ok, BytesSent}; - Error -> - Error - end; -sendfile_fallback_int(_File, _Sock, BytesSent, _ChunkSize, BytesSent) -> - {ok, BytesSent}. - -sendfile_send(Sock, Data, Old) -> - Len = iolist_size(Data), - case send(Sock, Data) of - ok -> - {ok, Len+Old}; - Else -> - Else - end. |