on master help sign in
Merge pull request #407 from awpr/clear_buffer_pool

Prevent no-longer-"useful" buffers from staying in the BufferPool.

commit66d99c44d5547291e4b2906941330b026d5be037 authorKazu Yamamoto <kazu@iij.ad.jp> dateWed 29 Jul 2015, 14:51 (11 years ago) parent6d2aaa7425ca72
3 files changed+50−2
warp/Network/Wai/Handler/Warp/Buffer.hs+1−1 warp/test/BufferPoolSpec.hs+47 warp/warp.cabal+2−1
warp/Network/Wai/Handler/Warp/Buffer.hs+1−1
@@ -69,7 +69,7 @@ getBuffer pool = do
6969{-# INLINE getBuffer #-}
7070
7171putBuffer :: BufferPool -> ByteString -> IO ()
72−putBuffer pool buffer = when (usefulBuffer buffer) $ writeIORef pool buffer
72+putBuffer pool buffer = writeIORef pool buffer
7373{-# INLINE putBuffer #-}
7474
7575withForeignBuffer :: ByteString -> ((Buffer, BufSize) -> IO Int) -> IO Int
warp/test/BufferPoolSpec.hsnew file+47
@@ -0,0 +1,47 @@
1+module BufferPoolSpec where
2+
3+import qualified Data.ByteString as B
4+import qualified Data.ByteString.Internal as B (ByteString(PS))
5+import Foreign.ForeignPtr (withForeignPtr)
6+import Foreign.Marshal.Utils (copyBytes)
7+import Foreign.Ptr (plusPtr)
8+
9+import Test.Hspec (Spec, hspec, shouldBe, describe, it)
10+
11+import Network.Wai.Handler.Warp.Buffer
12+ ( bufferSize
13+ , newBufferPool
14+ , withBufferPool
15+ )
16+import Network.Wai.Handler.Warp.Types (Buffer, BufSize)
17+
18+main :: IO ()
19+main = hspec spec
20+
21+-- Two ByteStrings each big enough to fill a 'bufferSize' buffer (16K).
22+wantData, otherData :: B.ByteString
23+wantData = B.replicate bufferSize 0xac
24+otherData = B.replicate bufferSize 0x77
25+
26+spec :: Spec
27+spec = describe "withBufferPool" $ do
28+ it "does not clobber buffers" $ do
29+ pool <- newBufferPool
30+ -- 'pool' contains B.empty; prime it to contain a real buffer.
31+ _ <- withBufferPool pool $ const $ return 0
32+ -- 'pool' contains a 16K buffer; fill it with \xac and keep the result.
33+ got <- withBufferPool pool $ blitBuffer wantData
34+ got `shouldBe` wantData
35+ -- 'pool' should now be empty and reallocate, rather than clobber the
36+ -- previous buffer.
37+ _ <- withBufferPool pool $ blitBuffer otherData
38+ got `shouldBe` wantData
39+
40+-- Fill the Buffer with the contents of the ByteString and return the number of
41+-- bytes written. To be used with 'withBufferPool'.
42+blitBuffer :: B.ByteString -> (Buffer, BufSize) -> IO Int
43+blitBuffer (B.PS fp off len) (dst, len') = withForeignPtr fp $ \ptr -> do
44+ let src = ptr `plusPtr` off
45+ n = min len len'
46+ copyBytes dst src n
47+ return n
warp/warp.cabal+2−1
@@ -122,7 +122,8 @@ Test-Suite doctest
122122
123123Test-Suite spec
124124 Main-Is: Spec.hs
125− Other-modules: ConduitSpec
125+ Other-modules: BufferPoolSpec
126+ ConduitSpec
126127 ExceptionSpec
127128 FdCacheSpec
128129 MultiMapSpec