aboutsummaryrefslogtreecommitdiffstats
path: root/erts/preloaded
diff options
context:
space:
mode:
authorLukas Larsson <[email protected]>2011-12-02 15:08:47 +0100
committerLukas Larsson <[email protected]>2011-12-02 15:08:47 +0100
commitf30ac8e5a84c550734b79a6d66639c4d3489c6fd (patch)
tree331a81551b21d75c41b5edc25b9077bfe2a8cf70 /erts/preloaded
parent7bd9c1f9a68a024958040fe5b77dacc73bb6c5ab (diff)
parent62fffa75e2003b3f19eb7614307942028a400fd1 (diff)
downloadotp-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.erl30
-rw-r--r--erts/preloaded/src/prim_inet.erl18
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