simple-sendfile 0.2.6 → 0.2.7
raw patch · 4 files changed
+99/−11 lines, 4 files
Files
- Network/Sendfile.hs +4/−2
- Network/Sendfile/BSD.hsc +43/−6
- Network/Sendfile/Linux.hsc +51/−2
- simple-sendfile.cabal +1/−1
Network/Sendfile.hs view
@@ -9,6 +9,10 @@ module Network.Sendfile ( sendfile , sendfileWithHeader+#if OS_BSD || OS_MacOS || OS_Linux+ , sendfileFd+ , sendfileFdWithHeader+#endif , FileRange(..) ) where @@ -20,8 +24,6 @@ import Network.Sendfile.BSD #elif OS_Linux import Network.Sendfile.Linux-#elif OS_Windows-import Network.Sendfile.Windows #else import Network.Sendfile.Fallback #endif
Network/Sendfile/BSD.hsc view
@@ -2,7 +2,9 @@ module Network.Sendfile.BSD ( sendfile+ , sendfileFd , sendfileWithHeader+ , sendfileFdWithHeader ) where import Control.Concurrent@@ -39,14 +41,29 @@ sendfile :: Socket -> FilePath -> FileRange -> IO () -> IO () sendfile sock path range hook = bracket setup teardown $ \fd ->+ sendfileFd sock fd range hook+ where+ setup = openFd path ReadOnly Nothing defaultFileFlags+ teardown = closeFd++-- |+-- Simple binding for sendfile() of BSD and MacOS.+--+-- - Used system calls: sendfile()+--+-- The fourth action argument is called when a file is sent as chunks.+-- Chucking is inevitable if the socket is non-blocking (this is the+-- default) and the file is large. The action is called after a chunk+-- is sent and bofore waiting the socket to be ready for writing.++sendfileFd :: Socket -> Fd -> FileRange -> IO () -> IO ()+sendfileFd sock fd range hook = alloca $ \sentp -> do let (off,len) = case range of EntireFile -> (0, entire) PartOfFile off' len' -> (fromInteger off', fromInteger len') sendloop dst fd off len sentp hook where- setup = openFd path ReadOnly Nothing defaultFileFlags- teardown = closeFd dst = Fd $ fdSocket sock sendloop :: Fd -> Fd -> COff -> COff -> Ptr COff -> IO () -> IO ()@@ -83,13 +100,35 @@ sendfileWithHeader :: Socket -> FilePath -> FileRange -> IO () -> [ByteString] -> IO () sendfileWithHeader sock path range hook hdr =- bracket setup teardown $ \fd -> alloca $ \sentp ->+ bracket setup teardown $ \fd -> sendfileFdWithHeader sock fd range hook hdr+ where+ setup = openFd path ReadOnly Nothing defaultFileFlags+ teardown = closeFd++-- |+-- Simple binding for sendfile() of BSD and MacOS.+--+-- - Used system calls: sendfile()+--+-- The fifth header is also sent with sendfile(). If the file is+-- small enough, the header and the file is send in a single TCP packet+-- on FreeBSD. MacOS sends the header and the file separately but it is+-- fast.+--+-- The fourth action argument is called when a file is sent as chunks.+-- Chucking is inevitable if the socket is non-blocking (this is the+-- default) and the file is large. The action is called after a chunk+-- is sent and bofore waiting the socket to be ready for writing.++sendfileFdWithHeader :: Socket -> Fd -> FileRange -> IO () -> [ByteString] -> IO ()+sendfileFdWithHeader sock fd range hook hdr =+ alloca $ \sentp -> if isFreeBSD && hlen >= 8192 then do -- If the length of the header is larger than 8191, -- threadWaitWrite does not come back on FreeBSD, sigh. -- We use writev() for the header and sendfile() for the file. sendMany sock hdr- sendfile sock path range hook+ sendfileFd sock fd range hook else do -- On MacOS, the header and the body are sent separately. -- But it's fast. the writev() and sendfile() combination@@ -105,8 +144,6 @@ threadWaitWrite dst sendloop dst fd newoff newlen sentp hook where- setup = openFd path ReadOnly Nothing defaultFileFlags- teardown = closeFd dst = Fd $ fdSocket sock hlen = fromIntegral . sum . map BS.length $ hdr
Network/Sendfile/Linux.hsc view
@@ -2,7 +2,9 @@ module Network.Sendfile.Linux ( sendfile+ , sendfileFd , sendfileWithHeader+ , sendfileFdWithHeader ) where import Control.Applicative@@ -47,6 +49,29 @@ sendfile :: Socket -> FilePath -> FileRange -> IO () -> IO () sendfile sock path range hook = bracket setup teardown $ \fd ->+ sendfileFd sock fd range hook+ where+ setup = openFd path ReadOnly Nothing defaultFileFlags+ teardown = closeFd++-- |+-- Simple binding for sendfile() of Linux.+-- Used system calls:+--+-- - EntireFile -- stat() and sendfile()+--+-- - PartOfFile -- sendfile()+--+-- If the size of the file is unknown when sending the entire file,+-- specifying PartOfFile is much faster.+--+-- The fourth action argument is called when a file is sent as chunks.+-- Chucking is inevitable if the socket is non-blocking (this is the+-- default) and the file is large. The action is called after a chunk+-- is sent and bofore waiting the socket to be ready for writing.++sendfileFd :: Socket -> Fd -> FileRange -> IO () -> IO ()+sendfileFd sock fd range hook = alloca $ \offp -> case range of EntireFile -> do poke offp 0@@ -59,8 +84,6 @@ let len' = fromIntegral len sendloop dst fd offp len' hook where- setup = openFd path ReadOnly Nothing defaultFileFlags- teardown = closeFd dst = Fd $ fdSocket sock sendloop :: Fd -> Fd -> Ptr COff -> CSize -> IO () -> IO ()@@ -113,6 +136,32 @@ -- Copying is much faster than syscall. sendAllMsgMore sock $ B.concat hdr sendfile sock path range hook++-- |+-- Simple binding for send() and sendfile() of Linux.+-- Used system calls:+--+-- - EntireFile -- send(), stat() and sendfile()+--+-- - PartOfFile -- send() and sendfile()+--+-- The fifth header is sent with send() + the MSG_MORE flag. If the+-- file is small enough, the header and the file is send in a single+-- TCP packet.+--+-- If the size of the file is unknown when sending the entire file,+-- specifying PartOfFile is much faster.+--+-- The fourth action argument is called when a file is sent as chunks.+-- Chucking is inevitable if the socket is non-blocking (this is the+-- default) and the file is large. The action is called after a chunk+-- is sent and bofore waiting the socket to be ready for writing.++sendfileFdWithHeader :: Socket -> Fd -> FileRange -> IO () -> [ByteString] -> IO ()+sendfileFdWithHeader sock fd range hook hdr = do+ -- Copying is much faster than syscall.+ sendAllMsgMore sock $ B.concat hdr+ sendfileFd sock fd range hook sendAllMsgMore :: Socket -> ByteString -> IO () sendAllMsgMore sock bs = do
simple-sendfile.cabal view
@@ -1,5 +1,5 @@ Name: simple-sendfile-Version: 0.2.6+Version: 0.2.7 Author: Kazu Yamamoto <kazu@iij.ad.jp> Maintainer: Kazu Yamamoto <kazu@iij.ad.jp> License: BSD3