diff options
author | Lukas Larsson <[email protected]> | 2014-01-27 12:01:45 +0100 |
---|---|---|
committer | Lukas Larsson <[email protected]> | 2014-01-27 14:48:50 +0100 |
commit | 0b36ce01e81744f4c0b41bfe1f62b4bf5d0ece97 (patch) | |
tree | ef403bfcfc33a41edb54309319a4cf39ca81ecab /erts/preloaded/src | |
parent | 045fcfc02ace59d07618f8983809236642bba630 (diff) | |
download | otp-0b36ce01e81744f4c0b41bfe1f62b4bf5d0ece97.tar.gz otp-0b36ce01e81744f4c0b41bfe1f62b4bf5d0ece97.tar.bz2 otp-0b36ce01e81744f4c0b41bfe1f62b4bf5d0ece97.zip |
erts/kernel: sendfile no longer uses async threads
This has been done because a slow client attack is possible if the
async thread pool is used. The scenario is:
Client does a request for a file and then slowly receives the file one
byte at a time. This will eventually fill the async thread pool with blocking
sendfile operations and thus starving the vm of all file operations.
If you still want to use the async threads pool for sendfile an option to
enable it has been introduced.
Diffstat (limited to 'erts/preloaded/src')
-rw-r--r-- | erts/preloaded/src/prim_file.erl | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/erts/preloaded/src/prim_file.erl b/erts/preloaded/src/prim_file.erl index 5999e98340..34679404a2 100644 --- a/erts/preloaded/src/prim_file.erl +++ b/erts/preloaded/src/prim_file.erl @@ -27,7 +27,7 @@ %% 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, sendfile/10, allocate/3]). + copy/3, sendfile/8, allocate/3]). %% Specialized file operations -export([open/1, open/3]). @@ -149,6 +149,9 @@ -define(POSIX_FADV_DONTNEED, 4). -define(POSIX_FADV_NOREUSE, 5). +%% Sendfile flags +-define(EFILE_SENDFILE_USE_THREADS, 1). + %%% BIFs @@ -582,13 +585,14 @@ write_file(_, _) -> % {error, enotsup}; sendfile(#file_descriptor{module = ?MODULE, data = {Port, _}}, Dest, Offset, Bytes, _ChunkSize, Headers, Trailers, - _Nodiskio, _MNowait, _Sync) -> + Flags) -> 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), + IntFlags = translate_sendfile_flags(Flags), try drv_command(Port, [<<?FILE_SENDFILE, DestFD:32, - 0:8, + IntFlags:8, Offset:64/unsigned, Bytes:64/unsigned, (iolist_size(Headers)):32/unsigned, @@ -601,6 +605,13 @@ sendfile(#file_descriptor{module = ?MODULE, data = {Port, _}}, {error,badarg} end. +translate_sendfile_flags([{use_threads,true}|T]) -> + ?EFILE_SENDFILE_USE_THREADS bor translate_sendfile_flags(T); +translate_sendfile_flags([_|T]) -> + translate_sendfile_flags(T); +translate_sendfile_flags([]) -> + 0. + %%%----------------------------------------------------------------- %%% Functions operating on files without handle to the file. ?DRV. |