Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package ghc-recv for openSUSE:Factory checked in at 2025-04-30 19:04:24 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/ghc-recv (Old) and /work/SRC/openSUSE:Factory/.ghc-recv.new.30101 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ghc-recv" Wed Apr 30 19:04:24 2025 rev:3 rq:1273529 version:0.1.1 Changes: -------- --- /work/SRC/openSUSE:Factory/ghc-recv/ghc-recv.changes 2023-04-04 21:22:49.802015700 +0200 +++ /work/SRC/openSUSE:Factory/.ghc-recv.new.30101/ghc-recv.changes 2025-04-30 19:04:26.890490675 +0200 @@ -1,0 +2,8 @@ +Tue Apr 22 01:25:40 UTC 2025 - Peter Simons <[email protected]> + +- Update recv to version 0.1.1. + Upstream added a new change log file in this release. With no + previous version to compare against, the automatic updater cannot + reliable determine the relevante entries for this release. + +------------------------------------------------------------------- Old: ---- recv-0.1.0.tar.gz New: ---- recv-0.1.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ ghc-recv.spec ++++++ --- /var/tmp/diff_new_pack.Js1dl6/_old 2025-04-30 19:04:27.546518021 +0200 +++ /var/tmp/diff_new_pack.Js1dl6/_new 2025-04-30 19:04:27.550518187 +0200 @@ -1,7 +1,7 @@ # # spec file for package ghc-recv # -# Copyright (c) 2023 SUSE LLC +# Copyright (c) 2025 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -20,7 +20,7 @@ %global pkgver %{pkg_name}-%{version} %bcond_with tests Name: ghc-%{pkg_name} -Version: 0.1.0 +Version: 0.1.1 Release: 0 Summary: Efficient network recv License: BSD-3-Clause @@ -91,6 +91,7 @@ %license LICENSE %files devel -f %{name}-devel.files +%doc ChangeLog.md %files -n ghc-%{pkg_name}-doc -f ghc-%{pkg_name}-doc.files %license LICENSE ++++++ recv-0.1.0.tar.gz -> recv-0.1.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/recv-0.1.0/ChangeLog.md new/recv-0.1.1/ChangeLog.md --- old/recv-0.1.0/ChangeLog.md 1970-01-01 01:00:00.000000000 +0100 +++ new/recv-0.1.1/ChangeLog.md 2001-09-09 03:46:40.000000000 +0200 @@ -0,0 +1,6 @@ +# ChangeLog for "recv" + +## v0.1.1 + +* Fixing the bug that the last chunk is skipped when the size is + insufficient [1031](https://github.com/yesodweb/wai/pull/1031) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/recv-0.1.0/Network/Socket/BufferPool/Buffer.hs new/recv-0.1.1/Network/Socket/BufferPool/Buffer.hs --- old/recv-0.1.0/Network/Socket/BufferPool/Buffer.hs 2001-09-09 03:46:40.000000000 +0200 +++ new/recv-0.1.1/Network/Socket/BufferPool/Buffer.hs 2001-09-09 03:46:40.000000000 +0200 @@ -1,16 +1,17 @@ module Network.Socket.BufferPool.Buffer ( - newBufferPool - , withBufferPool - , mallocBS - , copy - ) where + newBufferPool, + withBufferPool, + mallocBS, + copy, +) where import qualified Data.ByteString as BS -import Data.ByteString.Internal (ByteString(..), memcpy) -import Data.ByteString.Unsafe (unsafeTake, unsafeDrop) +import Data.ByteString.Internal (ByteString (..)) +import Data.ByteString.Unsafe (unsafeDrop, unsafeTake) import Data.IORef (newIORef, readIORef, writeIORef) import Foreign.ForeignPtr -import Foreign.Marshal.Alloc (mallocBytes, finalizerFree) +import Foreign.Marshal.Alloc (finalizerFree, mallocBytes) +import Foreign.Marshal.Utils (copyBytes) import Foreign.Ptr (castPtr, plusPtr) import Network.Socket.BufferPool.Types @@ -35,8 +36,10 @@ withBufferPool :: BufferPool -> (Buffer -> BufSize -> IO Int) -> IO ByteString withBufferPool (BufferPool l h ref) f = do buf0 <- readIORef ref - buf <- if BS.length buf0 >= l then return buf0 - else mallocBS h + buf <- + if BS.length buf0 >= l + then return buf0 + else mallocBS h consumed <- withForeignBuffer buf f writeIORef ref $ unsafeDrop consumed buf return $ unsafeTake consumed buf @@ -59,6 +62,6 @@ -- This function returns the point where the next copy should start. copy :: Buffer -> ByteString -> IO Buffer copy ptr (PS fp o l) = withForeignPtr fp $ \p -> do - memcpy ptr (p `plusPtr` o) (fromIntegral l) + copyBytes ptr (p `plusPtr` o) (fromIntegral l) return $ ptr `plusPtr` l {-# INLINE copy #-} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/recv-0.1.0/Network/Socket/BufferPool/Recv.hs new/recv-0.1.1/Network/Socket/BufferPool/Recv.hs --- old/recv-0.1.0/Network/Socket/BufferPool/Recv.hs 2001-09-09 03:46:40.000000000 +0200 +++ new/recv-0.1.1/Network/Socket/BufferPool/Recv.hs 2001-09-09 03:46:40.000000000 +0200 @@ -1,65 +1,24 @@ -{-# LANGUAGE ForeignFunctionInterface, OverloadedStrings #-} -{-# LANGUAGE CPP #-} +{-# LANGUAGE OverloadedStrings #-} module Network.Socket.BufferPool.Recv ( - receive - , makeRecvN - ) where + receive, + makeRecvN, +) where import qualified Data.ByteString as BS -import Data.ByteString.Internal (ByteString(..), unsafeCreate) +import Data.ByteString.Internal (ByteString (..), unsafeCreate) import Data.IORef -import Foreign.C.Error (eAGAIN, getErrno, throwErrno) -import Foreign.C.Types -import Foreign.Ptr (Ptr, castPtr) -import GHC.Conc (threadWaitRead) -import Network.Socket (Socket, withFdSocket) -import System.Posix.Types (Fd(..)) - -#ifdef mingw32_HOST_OS -import GHC.IO.FD (FD(..), readRawBufferPtr) -import Network.Socket.BufferPool.Windows -#endif +import Network.Socket (Socket, recvBuf) -import Network.Socket.BufferPool.Types import Network.Socket.BufferPool.Buffer +import Network.Socket.BufferPool.Types ---------------------------------------------------------------- -- | The receiving function with a buffer pool. -- The buffer pool is automatically managed. receive :: Socket -> BufferPool -> Recv -receive sock pool = withBufferPool pool $ \ptr size -> do -#if MIN_VERSION_network(3,1,0) - withFdSocket sock $ \fd -> do -#elif MIN_VERSION_network(3,0,0) - fd <- fdSocket sock -#else - let fd = fdSocket sock -#endif - let size' = fromIntegral size - fromIntegral <$> tryReceive fd ptr size' - ----------------------------------------------------------------- - -tryReceive :: CInt -> Buffer -> CSize -> IO CInt -tryReceive sock ptr size = go - where - go = do -#ifdef mingw32_HOST_OS - bytes <- windowsThreadBlockHack $ fromIntegral <$> readRawBufferPtr "tryReceive" (FD sock 1) (castPtr ptr) 0 size -#else - bytes <- c_recv sock (castPtr ptr) size 0 -#endif - if bytes == -1 then do - errno <- getErrno - if errno == eAGAIN then do - threadWaitRead (Fd sock) - go - else - throwErrno "tryReceive" - else - return bytes +receive sock pool = withBufferPool pool $ \ptr size -> recvBuf sock ptr size ---------------------------------------------------------------- @@ -71,6 +30,14 @@ -- When N is less than equal to 4096, the buffer pool is used. -- Otherwise, a new buffer is allocated. -- In this case, the global lock is taken. +-- +-- >>> :seti -XOverloadedStrings +-- >>> tryRecvN "a" 3 =<< _iorefRecv ["bcd"] +-- ("abc","d") +-- >>> tryRecvN "a" 3 =<< _iorefRecv ["bc"] +-- ("abc","") +-- >>> tryRecvN "a" 3 =<< _iorefRecv ["b"] +-- ("ab","") makeRecvN :: ByteString -> Recv -> IO RecvN makeRecvN bs0 recv = do ref <- newIORef bs0 @@ -89,34 +56,53 @@ tryRecvN :: ByteString -> Int -> IO ByteString -> IO (ByteString, ByteString) tryRecvN init0 siz0 recv - | siz0 <= len0 = return $ BS.splitAt siz0 init0 - | otherwise = go (init0:) (siz0 - len0) + | siz0 <= len0 = return $ BS.splitAt siz0 init0 + | otherwise = go (init0 :) (siz0 - len0) where len0 = BS.length init0 go build left = do bs <- recv let len = BS.length bs - if len == 0 then - return ("", "") - else if len >= left then do - let (consume, leftover) = BS.splitAt left bs - ret = concatN siz0 $ build [consume] - return (ret, leftover) - else do - let build' = build . (bs :) - left' = left - len - go build' left' + if len == 0 + then do + let cs = concatN (siz0 - left) $ build [] + return (cs, "") + else + if len >= left + then do + let (consume, leftover) = BS.splitAt left bs + ret = concatN siz0 $ build [consume] + return (ret, leftover) + else do + let build' = build . (bs :) + left' = left - len + go build' left' concatN :: Int -> [ByteString] -> ByteString -concatN total bss0 = unsafeCreate total $ \ptr -> goCopy bss0 ptr +-- Just because it's logical +concatN _ [] = "" +-- To avoid a copy if there's only one ByteString +concatN _ [bs] = bs +concatN total bss0 = + unsafeCreate total $ \ptr -> goCopy bss0 ptr where - goCopy [] _ = return () - goCopy (bs:bss) ptr = do + goCopy [] _ = return () + goCopy (bs : bss) ptr = do ptr' <- copy ptr bs goCopy bss ptr' -#ifndef mingw32_HOST_OS --- fixme: the type of the return value -foreign import ccall unsafe "recv" - c_recv :: CInt -> Ptr CChar -> CSize -> CInt -> IO CInt -#endif +-- | doctest only. Elements in the argument must not be empty. +_iorefRecv :: [ByteString] -> IO (IO ByteString) +_iorefRecv ini = do + ref <- newIORef ini + return $ recv ref + where + recv ref = do + xxs <- readIORef ref + case xxs of + [] -> do + writeIORef ref $ error "closed" + return "" + x : xs -> do + writeIORef ref xs + return x diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/recv-0.1.0/Network/Socket/BufferPool/Types.hs new/recv-0.1.1/Network/Socket/BufferPool/Types.hs --- old/recv-0.1.0/Network/Socket/BufferPool/Types.hs 2001-09-09 03:46:40.000000000 +0200 +++ new/recv-0.1.1/Network/Socket/BufferPool/Types.hs 2001-09-09 03:46:40.000000000 +0200 @@ -12,14 +12,15 @@ type BufSize = Int -- | Type for read buffer pool. -data BufferPool = BufferPool { - minBufSize :: Int -- ^ If the buffer is larger than or equal to this size, - -- the buffer is used. - -- Otherwise, a new buffer is allocated. - -- The thrown buffer is eventually freed. - , maxBufSize :: Int - , poolBuffer :: IORef ByteString - } +data BufferPool = BufferPool + { minBufSize :: Int + -- ^ If the buffer is larger than or equal to this size, + -- the buffer is used. + -- Otherwise, a new buffer is allocated. + -- The thrown buffer is eventually freed. + , maxBufSize :: Int + , poolBuffer :: IORef ByteString + } -- | Type for the receiving function with a buffer pool. type Recv = IO ByteString diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/recv-0.1.0/Network/Socket/BufferPool/Windows.hs new/recv-0.1.1/Network/Socket/BufferPool/Windows.hs --- old/recv-0.1.0/Network/Socket/BufferPool/Windows.hs 2001-09-09 03:46:40.000000000 +0200 +++ new/recv-0.1.1/Network/Socket/BufferPool/Windows.hs 1970-01-01 01:00:00.000000000 +0100 @@ -1,25 +0,0 @@ -{-# LANGUAGE CPP #-} -module Network.Socket.BufferPool.Windows - ( windowsThreadBlockHack - ) where - -#ifdef mingw32_HOST_OS -import Control.Concurrent.MVar -import Control.Concurrent -import qualified Control.Exception -import Control.Monad - --- | Allow main socket listening thread to be interrupted on Windows platform -windowsThreadBlockHack :: IO a -> IO a -windowsThreadBlockHack act = do - var <- newEmptyMVar :: IO (MVar (Either Control.Exception.SomeException a)) - -- Catch and rethrow even async exceptions, so don't bother with UnliftIO - void . forkIO $ Control.Exception.try act >>= putMVar var - res <- takeMVar var - case res of - Left e -> Control.Exception.throwIO e - Right r -> return r -#else -windowsThreadBlockHack :: IO a -> IO a -windowsThreadBlockHack = id -#endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/recv-0.1.0/Network/Socket/BufferPool.hs new/recv-0.1.1/Network/Socket/BufferPool.hs --- old/recv-0.1.0/Network/Socket/BufferPool.hs 2001-09-09 03:46:40.000000000 +0200 +++ new/recv-0.1.1/Network/Socket/BufferPool.hs 2001-09-09 03:46:40.000000000 +0200 @@ -21,22 +21,25 @@ -- When the buffer gets small -- and usefless, a new large buffer is allocated. module Network.Socket.BufferPool ( - -- * Recv - Recv - , receive - , BufferPool - , newBufferPool - , withBufferPool - -- * RecvN - , RecvN - , makeRecvN - -- * Types - , Buffer - , BufSize - -- * Utilities - , mallocBS - , copy - ) where + -- * Recv + Recv, + receive, + BufferPool, + newBufferPool, + withBufferPool, + + -- * RecvN + RecvN, + makeRecvN, + + -- * Types + Buffer, + BufSize, + + -- * Utilities + mallocBS, + copy, +) where import Network.Socket.BufferPool.Buffer import Network.Socket.BufferPool.Recv diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/recv-0.1.0/recv.cabal new/recv-0.1.1/recv.cabal --- old/recv-0.1.0/recv.cabal 2001-09-09 03:46:40.000000000 +0200 +++ new/recv-0.1.1/recv.cabal 2001-09-09 03:46:40.000000000 +0200 @@ -1,45 +1,51 @@ -Name: recv -Version: 0.1.0 -Synopsis: Efficient network recv -License: BSD3 -License-file: LICENSE -Author: Kazu Yamamoto -Maintainer: [email protected] -Homepage: http://github.com/yesodweb/wai -Category: Network -Build-Type: Simple -Cabal-Version: >= 1.10 -Stability: Stable -description: Network recv based on buffer pools +cabal-version: >=1.10 +name: recv +version: 0.1.1 +license: BSD3 +license-file: LICENSE +maintainer: [email protected] +author: Kazu Yamamoto +stability: Stable +homepage: http://github.com/yesodweb/wai +synopsis: Efficient network recv +description: Network recv based on buffer pools +category: Network +build-type: Simple +extra-source-files: ChangeLog.md -Library - Build-Depends: base >= 4.12 && < 5 - , bytestring >= 0.9.1.4 - , network >= 3.1.0 - Exposed-modules: Network.Socket.BufferPool - Other-modules: Network.Socket.BufferPool.Buffer - Network.Socket.BufferPool.Recv - Network.Socket.BufferPool.Types - Network.Socket.BufferPool.Windows - if impl(ghc >= 8) - Default-Extensions: Strict StrictData - Ghc-Options: -Wall - Default-Language: Haskell2010 +library + exposed-modules: Network.Socket.BufferPool + other-modules: + Network.Socket.BufferPool.Buffer + Network.Socket.BufferPool.Recv + Network.Socket.BufferPool.Types -Test-Suite spec - Main-Is: Spec.hs - Other-modules: BufferPoolSpec - Network.Socket.BufferPool - Network.Socket.BufferPool.Buffer - Network.Socket.BufferPool.Recv - Network.Socket.BufferPool.Types - Network.Socket.BufferPool.Windows - Hs-Source-Dirs: test, . - Type: exitcode-stdio-1.0 - Build-Depends: base >= 4.12 && < 5 - , bytestring >= 0.9.1.4 - , network >= 3.1.0 - , hspec - Ghc-Options: -Wall - Default-Language: Haskell2010 - Build-Tool-Depends: hspec-discover:hspec-discover + default-language: Haskell2010 + ghc-options: -Wall + build-depends: + base >=4.12 && <5, + bytestring >=0.9.1.4, + network >=3.1.0 + + if impl(ghc >=8) + default-extensions: Strict StrictData + +test-suite spec + type: exitcode-stdio-1.0 + main-is: Spec.hs + build-tool-depends: hspec-discover:hspec-discover + hs-source-dirs: test . + other-modules: + BufferPoolSpec + Network.Socket.BufferPool + Network.Socket.BufferPool.Buffer + Network.Socket.BufferPool.Recv + Network.Socket.BufferPool.Types + + default-language: Haskell2010 + ghc-options: -Wall + build-depends: + base >=4.12 && <5, + bytestring >=0.9.1.4, + network >=3.1.0, + hspec diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/recv-0.1.0/test/BufferPoolSpec.hs new/recv-0.1.1/test/BufferPoolSpec.hs --- old/recv-0.1.0/test/BufferPoolSpec.hs 2001-09-09 03:46:40.000000000 +0200 +++ new/recv-0.1.1/test/BufferPoolSpec.hs 2001-09-09 03:46:40.000000000 +0200 @@ -1,20 +1,20 @@ module BufferPoolSpec where import qualified Data.ByteString as B -import qualified Data.ByteString.Internal as B (ByteString(PS)) +import qualified Data.ByteString.Internal as B (ByteString (PS)) import Foreign.ForeignPtr (withForeignPtr) import Foreign.Marshal.Utils (copyBytes) import Foreign.Ptr (plusPtr) import Network.Socket.BufferPool -import Test.Hspec (Spec, hspec, shouldBe, describe, it) +import Test.Hspec (Spec, describe, hspec, it, shouldBe) main :: IO () main = hspec spec -- Two ByteStrings each big enough to fill a buffer (16K). wantData, otherData :: B.ByteString -wantData = B.replicate 16384 0xac +wantData = B.replicate 16384 0xac otherData = B.replicate 16384 0x77 spec :: Spec
