Skip to content

Commit

Permalink
if sendfile hits EOVERFLOW send the file from Erlang code instead
Browse files Browse the repository at this point in the history
  • Loading branch information
vinoski committed Dec 5, 2009
1 parent 9cee816 commit 082f043
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 13 deletions.
9 changes: 7 additions & 2 deletions c_src/yaws_sendfile_drv.c
Expand Up @@ -134,7 +134,11 @@ static size_t set_error_buffer(Buffer* b, int socket_fd, int err)
size_t result_size = sizeof *(b->result);
memset(b->result, 0, result_size);
put_int32(socket_fd, &(b->result->out_fd));
for (s = erl_errno_id(err), t = b->result->errno_string; *s; s++, t++) {
s = erl_errno_id(err);
if (strcmp(s, "unknown") == 0 && err == EOVERFLOW) {
s = "EOVERFLOW";
}
for (t = b->result->errno_string; *s; s++, t++) {
*t = tolower(*s);
}
*t = '\0';
Expand Down Expand Up @@ -238,7 +242,8 @@ static void yaws_sendfile_drv_ready_output(ErlDrvData handle, ErlDrvEvent ev)
return;
}
cur_offset = xfer->offset;
result = yaws_sendfile_call(sfd->socket_fd, xfer->file_fd, &xfer->offset, xfer->count);
result = yaws_sendfile_call(sfd->socket_fd, xfer->file_fd,
&xfer->offset, xfer->count);
if (result < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
off_t written = xfer->offset - cur_offset;
xfer->count -= written;
Expand Down
9 changes: 6 additions & 3 deletions src/yaws_sendfile.erl
Expand Up @@ -61,7 +61,8 @@ send(Out, Filename, Offset, Count) ->
call_port(
Socket_fd,
list_to_binary(
[<<Offset:64, Count2:64, Socket_fd:32>>, Filename, <<0:8>>]));
[<<Offset:64, Count2:64, Socket_fd:32>>,
Filename, <<0:8>>]));
Error3 ->
Error3
end
Expand Down Expand Up @@ -103,9 +104,11 @@ loop(Port) ->
unregister(?MODULE),
exit(shutdown);
{'EXIT', Port, Posix_error} ->
error_logger:format("Fatal error: sendfile port died, error ~p~n", [Posix_error]),
error_logger:format("Fatal error: sendfile port died, error ~p~n",
[Posix_error]),
exit(Posix_error);
{'EXIT', error, Reason} ->
error_logger:format("Fatal error: sendfile driver failure: ~p~n", [Reason]),
error_logger:format("Fatal error: sendfile driver failure: ~p~n",
[Reason]),
exit(Reason)
end.
37 changes: 29 additions & 8 deletions src/yaws_sendfile_compat.erl
Expand Up @@ -9,6 +9,8 @@
-include_lib("kernel/include/file.hrl").
-include("yaws_configure.hrl").

-include("../include/yaws.hrl").

%% will be true for MacOsX, FreeBSD, Linux
-ifdef(HAVE_SENDFILE).

Expand All @@ -21,18 +23,32 @@ stop() ->
init(ShLib) ->
yaws_sendfile:init(ShLib).
send(Out, FileName) ->
yaws_sendfile:send(Out, FileName).
case yaws_sendfile:send(Out, FileName) of
{error, eoverflow} ->
compat_send(Out, FileName, 0, all);
Other ->
Other
end.
send(Out, FileName, Offset) ->
yaws_sendfile:send(Out, FileName, Offset).
case yaws_sendfile:send(Out, FileName, Offset) of
{error, eoverflow} ->
compat_send(Out, FileName, Offset, all);
Other ->
Other
end.
send(Out, FileName, Offset, Count) ->
yaws_sendfile:send(Out, FileName, Offset, Count).

case yaws_sendfile:send(Out, FileName, Offset, Count) of
{error, eoverflow} ->
compat_send(Out, FileName, Offset, Count);
Other ->
Other
end.

-else.

-include("../include/yaws.hrl").
%% Emulate sendfile, this is true for win32, qnx, solaris. OpenBSD,NetBSD I
%% still don't know

%% Emulate sendfile, this is true for win32, qnx, solaris. OpenBSD,NetBSD I still don't know
enabled() ->
false.
start_link() ->
Expand All @@ -46,6 +62,11 @@ send(Out, Filename) ->
send(Out, Filename, Offset) ->
send(Out, Filename, Offset, all).
send(Out, Filename, Offset, Count) ->
compat_send(Out, Filename, Offset, Count).

-endif.

compat_send(Out, Filename, Offset, Count) ->
case file:open(Filename, [read, binary, raw]) of
{ok, Fd} ->
file:position(Fd, {bof, Offset}),
Expand All @@ -71,7 +92,8 @@ loop_send(Fd, ChunkSize, {ok, Bin}, Out, Count) ->
if Sz < Count ->
case gen_tcp:send(Out, Bin) of
true ->
loop_send(Fd, ChunkSize, file:read(Fd, ChunkSize), Out, Count-Sz);
loop_send(Fd, ChunkSize, file:read(Fd, ChunkSize),
Out, Count-Sz);
Err ->
Err
end;
Expand All @@ -85,4 +107,3 @@ loop_send(_Fd, _, Err, _,_) ->
Err.


-endif.

0 comments on commit 082f043

Please sign in to comment.