diff options
author | Lukas Larsson <[email protected]> | 2011-12-02 15:08:47 +0100 |
---|---|---|
committer | Lukas Larsson <[email protected]> | 2011-12-02 15:08:47 +0100 |
commit | f30ac8e5a84c550734b79a6d66639c4d3489c6fd (patch) | |
tree | 331a81551b21d75c41b5edc25b9077bfe2a8cf70 /erts/preloaded | |
parent | 7bd9c1f9a68a024958040fe5b77dacc73bb6c5ab (diff) | |
parent | 62fffa75e2003b3f19eb7614307942028a400fd1 (diff) | |
download | otp-f30ac8e5a84c550734b79a6d66639c4d3489c6fd.tar.gz otp-f30ac8e5a84c550734b79a6d66639c4d3489c6fd.tar.bz2 otp-f30ac8e5a84c550734b79a6d66639c4d3489c6fd.zip |
Merge branch 'ta/sendfile/OTP-9240'
* ta/sendfile/OTP-9240: (31 commits)
Add sendfile server printouts
Skip recv/send during tests for fallback platforms
Remove header/trailer support
Remove windows implementation
Expand sendfile documentation
Only allow tcp sockets as target for sendfile
Move sendfile api to file module
Preliminary work on header/trailer
Use free_sendfile explicitly for non-async
Remove debug printouts
Add tests for send/recv/sendfile interactions
Remove tests for file_server sendfile
sendfile caller now has to be the controlling_process
Remove support for file_server, sendfile has to be raw
Set chunk size to 3 GB
Change type of fd to be ErlDrvEvent
Add ifdef's for HAVE_SENDFILE
Fix freebsd support for sendfile
Change nbytes to 64 bit
Implement ignorefd for TCP
...
Diffstat (limited to 'erts/preloaded')
-rw-r--r-- | erts/preloaded/src/prim_file.erl | 30 | ||||
-rw-r--r-- | erts/preloaded/src/prim_inet.erl | 18 |
2 files changed, 45 insertions, 3 deletions
diff --git a/erts/preloaded/src/prim_file.erl b/erts/preloaded/src/prim_file.erl index 30b7a5246a..7316e0be99 100644 --- a/erts/preloaded/src/prim_file.erl +++ b/erts/preloaded/src/prim_file.erl @@ -26,7 +26,8 @@ %% Generic file contents operations -export([open/2, close/1, datasync/1, sync/1, advise/4, position/2, truncate/1, - write/2, pwrite/2, pwrite/3, read/2, read_line/1, pread/2, pread/3, copy/3]). + write/2, pwrite/2, pwrite/3, read/2, read_line/1, pread/2, pread/3, + copy/3, sendfile/10]). %% Specialized file operations -export([open/1, open/3]). @@ -98,6 +99,7 @@ -define(FILE_READ_LINE, 29). -define(FILE_FDATASYNC, 30). -define(FILE_ADVISE, 31). +-define(FILE_SENDFILE, 32). %% Driver responses -define(FILE_RESP_OK, 0). @@ -537,7 +539,31 @@ write_file(File, Bin) when (is_list(File) orelse is_binary(File)) -> end; write_file(_, _) -> {error, badarg}. - + + +%% Returns {error, Reason} | {ok, BytesCopied} +%sendfile(_,_,_,_,_,_,_,_,_,_) -> +% {error, enotsup}; +sendfile(#file_descriptor{module = ?MODULE, data = {Port, _}}, + Dest, Offset, Bytes, _ChunkSize, Headers, Trailers, + _Nodiskio, _MNowait, _Sync) -> + case erlang:port_get_data(Dest) of + Data when Data == inet_tcp; Data == inet6_tcp -> + ok = inet:lock_socket(Dest,true), + {ok, DestFD} = prim_inet:getfd(Dest), + try drv_command(Port, [<<?FILE_SENDFILE, DestFD:32, + 0:8, + Offset:64/unsigned, + Bytes:64/unsigned, + (iolist_size(Headers)):32/unsigned, + (iolist_size(Trailers)):32/unsigned>>, + Headers,Trailers]) + after + ok = inet:lock_socket(Dest,false) + end; + _Else -> + {error,badarg} + end. %%%----------------------------------------------------------------- diff --git a/erts/preloaded/src/prim_inet.erl b/erts/preloaded/src/prim_inet.erl index f144f73d68..0cedd284db 100644 --- a/erts/preloaded/src/prim_inet.erl +++ b/erts/preloaded/src/prim_inet.erl @@ -36,7 +36,8 @@ -export([recvfrom/2, recvfrom/3]). -export([setopt/3, setopts/2, getopt/2, getopts/2, is_sockopt_val/2]). -export([chgopt/3, chgopts/2]). --export([getstat/2, getfd/1, getindex/1, getstatus/1, gettype/1, +-export([getstat/2, getfd/1, ignorefd/2, + getindex/1, getstatus/1, gettype/1, getifaddrs/1, getiflist/1, ifget/3, ifset/3, gethostname/1]). -export([getservbyname/3, getservbyport/3]). @@ -842,6 +843,21 @@ getfd(S) when is_port(S) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% +%% IGNOREFD(insock(),boolean()) -> {ok,integer()} | {error, Reason} +%% +%% steal internal file descriptor +%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +ignorefd(S,Bool) when is_port(S) -> + Val = if Bool -> 1; true -> 0 end, + case ctl_cmd(S, ?INET_REQ_IGNOREFD, [Val]) of + {ok, _} -> ok; + Error -> Error + end. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% %% GETIX(insock()) -> {ok,integer()} | {error, Reason} %% %% get internal socket index |