packages feed

simple-sendfile 0.2.12 → 0.2.13

raw patch · 2 files changed

+37/−24 lines, 2 files

Files

Network/Sendfile/Linux.hsc view
@@ -11,17 +11,17 @@ import Control.Exception import Control.Monad import Data.ByteString as B-import Data.ByteString.Unsafe+import Data.ByteString.Internal import Data.Int import Foreign.C.Error (eAGAIN, getErrno, throwErrno) import Foreign.C.Types import Foreign.Marshal (alloca)-import Foreign.Ptr (Ptr)+import Foreign.Ptr (Ptr, plusPtr, castPtr)+import Foreign.ForeignPtr import Foreign.Storable (poke) import GHC.Conc (threadWaitWrite) import Network.Sendfile.Types import Network.Socket-import Network.Socket.Internal (throwSocketErrorIfMinus1RetryMayBlock) import System.Posix.Files import System.Posix.IO import System.Posix.Types@@ -78,16 +78,16 @@             -- System call is very slow. Use PartOfFile instead.             len <- fileSize <$> getFdStatus fd             let len' = fromIntegral len-            sendloop dst fd offp len' hook+            sendfileloop dst fd offp len' hook         PartOfFile off len -> do             poke offp (fromIntegral off)             let len' = fromIntegral len-            sendloop dst fd offp len' hook+            sendfileloop dst fd offp len' hook   where     dst = Fd $ fdSocket sock -sendloop :: Fd -> Fd -> Ptr COff -> CSize -> IO () -> IO ()-sendloop dst src offp len hook = do+sendfileloop :: Fd -> Fd -> Ptr COff -> CSize -> IO () -> IO ()+sendfileloop dst src offp len hook = do     -- Multicore IO manager use edge-trigger mode.     -- So, calling threadWaitWrite only when errnor is eAGAIN.     bytes <- c_sendfile dst src offp len@@ -96,14 +96,14 @@             errno <- getErrno             if errno == eAGAIN then do                 threadWaitWrite dst-                sendloop dst src offp len hook+                sendfileloop dst src offp len hook               else-                throwErrno "Network.SendFile.Linux.sendloop"+                throwErrno "Network.SendFile.Linux.sendfileloop"         0  -> return () -- the file is truncated         _  -> do             hook             let left = len - fromIntegral bytes-            when (left /= 0) $ sendloop dst src offp left hook+            when (left /= 0) $ sendfileloop dst src offp left hook  -- Dst Src in order. take care foreign import ccall unsafe "sendfile"@@ -134,7 +134,7 @@ sendfileWithHeader :: Socket -> FilePath -> FileRange -> IO () -> [ByteString] -> IO () sendfileWithHeader sock path range hook hdr = do     -- Copying is much faster than syscall.-    sendAllMsgMore sock $ B.concat hdr+    sendMsgMore sock $ B.concat hdr     sendfile sock path range hook  -- |@@ -160,21 +160,34 @@ 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+    sendMsgMore sock $ B.concat hdr     sendfileFd sock fd range hook -sendAllMsgMore :: Socket -> ByteString -> IO ()-sendAllMsgMore sock bs = do-    sent <- sendMsgMore sock bs-    when (sent < B.length bs) $ sendAllMsgMore sock (B.drop sent bs)+sendMsgMore :: Socket -> ByteString -> IO ()+sendMsgMore sock bs = withForeignPtr fptr $ \ptr -> do+    let buf = castPtr (ptr `plusPtr` off)+        siz = fromIntegral len+    sendloop s buf siz+  where+    MkSocket s _ _ _ _ = sock+    PS fptr off len = bs -sendMsgMore :: Socket -> ByteString -> IO Int-sendMsgMore (MkSocket s _ _ _ _) xs =-    unsafeUseAsCStringLen xs $ \(str, len) ->-    fromIntegral <$> throwSocketErrorIfMinus1RetryMayBlock-                         "sendMsgMore"-                         (threadWaitWrite (fromIntegral s))-                         (c_send s str (fromIntegral len) (#const MSG_MORE))+sendloop :: CInt -> Ptr CChar -> CSize -> IO ()+sendloop s buf len = do+    bytes <- c_send s buf len (#const MSG_MORE)+    if bytes == -1 then do+        errno <- getErrno+        if errno == eAGAIN then do+            threadWaitWrite (Fd s)+            sendloop s buf len+          else+            throwErrno "Network.SendFile.Linux.sendloop"+      else do+        let sent = fromIntegral bytes+        when (sent /= len) $ do+            let left = len - sent+                ptr = buf `plusPtr` fromIntegral bytes+            sendloop s ptr left  foreign import ccall unsafe "send"   c_send :: CInt -> Ptr CChar -> CSize -> CInt -> IO (#type ssize_t)
simple-sendfile.cabal view
@@ -1,5 +1,5 @@ Name:                   simple-sendfile-Version:                0.2.12+Version:                0.2.13 Author:                 Kazu Yamamoto <kazu@iij.ad.jp> Maintainer:             Kazu Yamamoto <kazu@iij.ad.jp> License:                BSD3