Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Use file:sendfile/5 if available

  • Loading branch information...
commit 4113a99e63cce094e15c9f2a3335090498a9c860 1 parent 7464efc
@tuncer tuncer authored vinoski committed
View
2  c_src/Makefile
@@ -12,7 +12,7 @@ else
PRIV_FILES= ../priv/lib/setuid_drv.$(DLL) $(EPAM)
endif
-ifeq ($(HAVE_SENDFILE),true)
+ifeq ($(HAVE_YAWS_SENDFILE),true)
PRIV_FILES += ../priv/lib/yaws_sendfile_drv.$(DLL)
endif
View
4 c_src/yaws_sendfile_drv.c
@@ -2,7 +2,7 @@
/* author: vinoski@ieee.org */
/* Created : 09 Nov 2008 by Steve Vinoski <vinoski@ieee.org> */
-#ifdef HAVE_SENDFILE
+#ifdef HAVE_YAWS_SENDFILE
#include <errno.h>
#include <stdint.h>
@@ -328,4 +328,4 @@ DRIVER_INIT(yaws_sendfile_drv)
#error "yaws_sendfile_drv not supported on this platform"
-#endif /* HAVE_SENDFILE */
+#endif /* HAVE_YAWS_SENDFILE */
View
18 configure.in
@@ -213,7 +213,7 @@ dnl in /usr/include/pam... I'm too sick of M4 at this very moment to write
dnl a test that searches for the files, so hard coded for now...
dnl or use --with-extrainclude=....
CFLAGS="$CFLAGS -I/usr/include/security"
-HAVE_SENDFILE=false
+HAVE_YAWS_SENDFILE=false
case "$host_os" in
*linux*)
@@ -242,7 +242,7 @@ case "$host_os" in
AC_SUBST(LD_SHARED)
FPIC=-fpic
AC_SUBST(FPIC)
- HAVE_SENDFILE=true
+ HAVE_YAWS_SENDFILE=true
;;
*solaris*)
@@ -259,7 +259,7 @@ case "$host_os" in
AC_DEFINE(BSD)
case "$host_os" in
freebsd*)
- HAVE_SENDFILE=true
+ HAVE_YAWS_SENDFILE=true
;;
bsdi*)
BSDI=bsdi
@@ -274,7 +274,7 @@ case "$host_os" in
;;
*darwin*)
AC_LANG(C)
- AC_CHECK_LIB([c],[sendfile],[HAVE_SENDFILE=true])
+ AC_CHECK_LIB([c],[sendfile],[HAVE_YAWS_SENDFILE=true])
case "$host_os" in
darwin1?*)
AC_LANG(Erlang)
@@ -316,8 +316,14 @@ case "$host_os" in
esac
AC_ARG_ENABLE(sendfile, AS_HELP_STRING([--disable-sendfile], [disables use of sendfile system call]),
- [ test "$enableval" = no && HAVE_SENDFILE=false ])
-AC_SUBST(HAVE_SENDFILE)
+ [ test "$enableval" = no && HAVE_YAWS_SENDFILE=false ])
+file_sendfile=`"${ERL}" -noshell -eval 'io:format("~p~n",[[erlang:function_exported(file, sendfile, 5)]]), erlang:halt().' | tail -1`
+if [ "$file_sendfile" = true ] ; then
+ HAVE_YAWS_SENDFILE=false
+ AC_MSG_NOTICE(found file:sendfile/5)
+fi
+AC_SUBST(HAVE_YAWS_SENDFILE)
+
YTOP=`pwd`
AC_SUBST(YTOP)
AC_OUTPUT(include.mk)
View
6 include.mk.in
@@ -22,7 +22,7 @@ DEFAULT_CHARSET=@DEFAULT_CHARSET@
EPAM = @EPAM@
EXTRAINCLUDE = @EXTRAINCLUDE@
ERLBINDIR = @ERLBINDIR@
-HAVE_SENDFILE = @HAVE_SENDFILE@
+HAVE_YAWS_SENDFILE = @HAVE_YAWS_SENDFILE@
BITS_SUPPORT = @BITS_SUPPORT@
ifdef debug
@@ -43,8 +43,8 @@ endif
CC=@CC@
CFLAGS=@CFLAGS@
-ifeq ($(HAVE_SENDFILE),true)
-CFLAGS += -DHAVE_SENDFILE
+ifeq ($(HAVE_YAWS_SENDFILE),true)
+CFLAGS += -DHAVE_YAWS_SENDFILE
endif
LINKER=@LINKER@
LDFLAGS=@LDFLAGS@
View
13 rebar.config
@@ -3,19 +3,22 @@
{plugins, [rebar_reltool_link]}.
{sub_dirs, ["rel"]}.
-{erl_opts, [{platform_define,
- "(linux|freebsd|darwin)", 'HAVE_SENDFILE'},
+{erl_opts, [%% OTP R11 - R15A -> yaws_sendfile_drv or compat_send
+ {platform_define,
+ "R1([1-4]|5A).*(linux|freebsd|darwin)", 'HAVE_YAWS_SENDFILE'},
+ {platform_define, "R1([1-4]|5A).*", 'NO_FILE_SENDFILE'},
no_debug_info,
{src_dirs, ["src", "examples/src"]},
warnings_as_errors]}.
{port_envs, [{"CFLAGS", "$CFLAGS -g -O3 -Wall -I/usr/include/security"},
- {"(linux|freebsd|dragonfly|solaris|darwin)",
- "DRV_CFLAGS", "$DRV_CFLAGS -DHAVE_SENDFILE"}]}.
+ {"R1([1-4]|5A).*(linux|freebsd|darwin)",
+ "DRV_CFLAGS", "$DRV_CFLAGS -DHAVE_YAWS_SENDFILE"}]}.
{port_specs, [{"priv/lib/epam.so", ["c_src/epam.c"]},
{"priv/lib/setuid_drv.so", ["c_src/setuid_drv.c"]},
- {"priv/lib/yaws_sendfile_drv.so",
+ {"R1([1-4]|5A).*(linux|freebsd|darwin)",
+ "priv/lib/yaws_sendfile_drv.so",
["c_src/yaws_sendfile_drv.c", "c_src/hashtable.c"]}]}.
{pre_hooks, [{compile, "./scripts/rebar-pre-script"},
View
3  scripts/rebar-pre-script
@@ -51,7 +51,8 @@ if [ -n "$need_mime" ]; then
fi
if [ ! -f yaws_configure.hrl ]; then
- echo '%% rebar sets HAVE_SENDFILE in erlc command line' > yaws_configure.hrl
+ echo '%% rebar sets HAVE_YAWS_SENDFILE in erlc command line' \
+ > yaws_configure.hrl
[ $? -eq 0 ] || fail
fi
tmpgen=`mktemp /tmp/${script}.XXXXXX` || fail
View
4 src/Makefile
@@ -82,8 +82,8 @@ yaws_generated.erl: yaws_generated.template ../vsn.mk
../scripts/gen-yaws-generated true > yaws_generated.erl
yaws_configure.hrl: ../vsn.mk ../include.mk
- if [ $(HAVE_SENDFILE) = "true" ]; then \
- echo "-define(HAVE_SENDFILE, true)." > yaws_configure.hrl; \
+ if [ $(HAVE_YAWS_SENDFILE) = "true" ]; then \
+ echo "-define(HAVE_YAWS_SENDFILE, true)." > yaws_configure.hrl; \
else touch yaws_configure.hrl; fi
View
85 src/yaws_sendfile.erl
@@ -11,15 +11,19 @@
-include("yaws_configure.hrl").
-include("../include/yaws.hrl").
+-include_lib("kernel/include/file.hrl").
--ifdef(HAVE_SENDFILE).
+-ifndef(HAVE_YAWS_SENDFILE).
+-ifndef(NO_FILE_SENDFILE).
+-define(HAVE_FILE_SENDFILE, 1).
+-endif.
+-endif.
+
+-ifdef(HAVE_YAWS_SENDFILE).
-behavior(gen_server).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2,
code_change/3]).
-
--include_lib("kernel/include/file.hrl").
-
-endif.
send(Out, Filename) ->
@@ -27,7 +31,50 @@ send(Out, Filename) ->
send(Out, Filename, Offset) ->
send(Out, Filename, Offset, all).
--ifdef(HAVE_SENDFILE).
+bytes_to_transfer(Filename, Offset, Count) ->
+ case Count of
+ all ->
+ case file:read_file_info(Filename) of
+ {ok, #file_info{size = Size}} ->
+ Size - Offset;
+ Error ->
+ Error
+ end;
+ Count when is_integer(Count) ->
+ Count;
+ _ ->
+ {error, badarg}
+ end.
+
+-ifdef(HAVE_FILE_SENDFILE). %% OTP >= R15B; use file:sendfile/5
+
+enabled() ->
+ true.
+send(Out, Filename, Offset, Count) ->
+ Count1 = bytes_to_transfer(Filename, Offset, Count),
+ case Count1 of
+ {error, _}=Error1 ->
+ Error1;
+ _ ->
+ case file:open(Filename, [raw, read, binary]) of
+ {ok, RawFile} ->
+ Res = file:sendfile(RawFile, Out, Offset, Count1, []),
+ ok = file:close(RawFile),
+ Res;
+ Error2 ->
+ Error2
+ end
+ end.
+start_link() ->
+ ignore.
+start() ->
+ ignore.
+stop() ->
+ ok.
+
+-else.
+
+-ifdef(HAVE_YAWS_SENDFILE).
start_link() ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
@@ -39,28 +86,16 @@ enabled() ->
true.
send(Out, Filename, Offset, Count) ->
- Count1 = case Count of
- all ->
- case file:read_file_info(Filename) of
- {ok, #file_info{size = Size}} ->
- Size - Offset;
- Error ->
- Error
- end;
- Count when is_integer(Count) ->
- Count;
- _ ->
- {error, badarg}
- end,
+ Count1 = bytes_to_transfer(Filename, Offset, Count),
case Count1 of
- {error, _}=Error2 ->
- Error2;
+ {error, _}=Error ->
+ Error;
_ ->
case prim_inet:getfd(Out) of
{ok, SocketFd} ->
do_send(Out, SocketFd, Filename, Offset, Count1);
- Error3 ->
- Error3
+ Error2 ->
+ Error2
end
end.
@@ -149,14 +184,14 @@ do_send(Out, SocketFd, Filename, Offset, Count) ->
enabled() ->
false.
+send(Out, Filename, Offset, Count) ->
+ compat_send(Out, Filename, Offset, Count).
start_link() ->
ignore.
start() ->
ignore.
stop() ->
ok.
-send(Out, Filename, Offset, Count) ->
- compat_send(Out, Filename, Offset, Count).
-endif.
@@ -203,3 +238,5 @@ loop_send(Fd, ChunkSize, {ok, Bin}, Out, Count) ->
end;
loop_send(_Fd, _, Err, _,_) ->
Err.
+
+-endif.
View
2  win32/include.mk
@@ -22,7 +22,7 @@ DEFAULT_CHARSET=
EPAM = ../priv/epam
EXTRAINCLUDE =
ERLBINDIR = /usr/lib/erlang/bin
-HAVE_SENDFILE = true
+HAVE_YAWS_SENDFILE = true
ifdef debug
ERLC_FLAGS+=-Ddebug

0 comments on commit 4113a99

Please sign in to comment.
Something went wrong with that request. Please try again.