packages feed

unagi-chan 0.4.0.0 → 0.4.1.0

raw patch · 9 files changed

+45/−10 lines, 9 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Control.Concurrent.Chan.Unagi: tryRead :: Element a -> IO (Maybe a)
- Control.Concurrent.Chan.Unagi.Bounded: tryRead :: Element a -> IO (Maybe a)
- Control.Concurrent.Chan.Unagi.NoBlocking: tryRead :: Element a -> IO (Maybe a)
- Control.Concurrent.Chan.Unagi.NoBlocking: tryReadNext :: Stream a -> IO (Next a)
- Control.Concurrent.Chan.Unagi.NoBlocking.Unboxed: tryRead :: Element a -> IO (Maybe a)
- Control.Concurrent.Chan.Unagi.NoBlocking.Unboxed: tryReadNext :: Stream a -> IO (Next a)
- Control.Concurrent.Chan.Unagi.Unboxed: tryRead :: Element a -> IO (Maybe a)
+ Control.Concurrent.Chan.Unagi: [tryRead] :: Element a -> IO (Maybe a)
+ Control.Concurrent.Chan.Unagi.Bounded: [tryRead] :: Element a -> IO (Maybe a)
+ Control.Concurrent.Chan.Unagi.Bounded: estimatedLength :: InChan a -> IO Int
+ Control.Concurrent.Chan.Unagi.NoBlocking: [tryReadNext] :: Stream a -> IO (Next a)
+ Control.Concurrent.Chan.Unagi.NoBlocking: [tryRead] :: Element a -> IO (Maybe a)
+ Control.Concurrent.Chan.Unagi.NoBlocking.Unboxed: [tryReadNext] :: Stream a -> IO (Next a)
+ Control.Concurrent.Chan.Unagi.NoBlocking.Unboxed: [tryRead] :: Element a -> IO (Maybe a)
+ Control.Concurrent.Chan.Unagi.Unboxed: [tryRead] :: Element a -> IO (Maybe a)
- Control.Concurrent.Chan.Unagi.NoBlocking.Unboxed: class (Prim a, Eq a) => UnagiPrim a where atomicUnicorn = Nothing
+ Control.Concurrent.Chan.Unagi.NoBlocking.Unboxed: class (Prim a, Eq a) => UnagiPrim a
- Control.Concurrent.Chan.Unagi.Unboxed: class (Prim a, Eq a) => UnagiPrim a where atomicUnicorn = Nothing
+ Control.Concurrent.Chan.Unagi.Unboxed: class (Prim a, Eq a) => UnagiPrim a

Files

CHANGELOG.markdown view
@@ -38,3 +38,7 @@  - `tryReadChan` now returns an `(Element a, IO a)` tuple, where the `snd` is a blocking read action  - depend atomic-primops >= 0.8++### 0.4.1.0++- add non-atomic `estimatedLength`, thanks to danclien
src/Control/Concurrent/Chan/Unagi/Bounded.hs view
@@ -22,6 +22,7 @@     , tryReadChan     , Element(..)     , getChanContents+    , estimatedLength     -- ** Writing     , writeChan     , tryWriteChan
src/Control/Concurrent/Chan/Unagi/Bounded/Internal.hs view
@@ -6,6 +6,7 @@     , newChanStarting, writeChan, readChan, readChanOnException     , tryWriteChan, tryReadChan     , dupChan+    , estimatedLength     )     where @@ -235,16 +236,25 @@ -- be. tryWriteChan :: InChan a -> a -> IO Bool {-# INLINE tryWriteChan #-}-tryWriteChan c@(InChan readCounterReader _ (ChanEnd _ boundsMn1 _ counter _)) = \a-> do+tryWriteChan c@(InChan _ _ (ChanEnd _ boundsMn1 _ _ _)) = \a-> do     -- Similar caveats w/r/t counter overflow correctness as elsewhere apply     -- here: where this would lap and give incorrect results we have already     -- died with OOM:-    ixR <- readCounterReader-    ixW <- readCounter counter-    if ixW - ixR > boundsMn1 +    len <- estimatedLength c+    if len > boundsMn1          then return False         else writeChanWithBlocking False c a >> return True +-- | Return the estimated length of a bounded queue+--+-- The more concurrent writes and reads that are happening, the more inaccurate+-- the estimate of the chan's size is likely to be.+estimatedLength :: InChan a -> IO Int+{-# INLINE estimatedLength #-}+estimatedLength (InChan readCounterReader _ (ChanEnd _ _ _ counter _)) = do+    ixR <- readCounterReader+    ixW <- readCounter counter+    return $ ixW - ixR  -- The core of our 'read' operations, with exception handler: readSegIxUnmasked :: (IO a -> IO a) -> (StreamSegment a, Int) -> IO a
src/Control/Concurrent/Chan/Unagi/Internal.hs view
@@ -10,6 +10,8 @@     , dupChan, tryReadChan     -- For Unagi.NoBlocking:     , moveToNextCell, waitingAdvanceStream, newSegmentSource+    -- sanity tests:+    , assertionCanary     )     where @@ -361,3 +363,15 @@ --   Readers blocked indefinitely should eventually raise a --   BlockedIndefinitelyOnMVar. -- ----------+++-- This could go anywhere, and lets us ensure that assertions are turned on+-- when running test suite.+assertionCanary :: IO Bool+assertionCanary = do+    assertionsWorking <- try $ assert False $ return ()+    return $+      case assertionsWorking of+           Left (AssertionFailed _) -> True+           _                        -> False+
src/Control/Concurrent/Chan/Unagi/Unboxed/Internal.hs view
@@ -72,7 +72,7 @@ -- For instances: import Data.Typeable(Typeable) import Data.Int(Int8,Int16,Int32,Int64)-import Data.Word(Word,Word8,Word16,Word32,Word64)+import Data.Word  import Utilities import Control.Concurrent.Chan.Unagi.Constants
tests/Main.hs view
@@ -20,14 +20,17 @@ -- Other import Atomics import IndexedMVar+import Control.Concurrent.Chan.Unagi.Internal(assertionCanary)  main :: IO () main = do      -- Make sure testing environment is sane:     assertionsWorking <- try $ assert False $ return ()+    assertionsWorkingInLib <- assertionCanary     case assertionsWorking of-         Left (AssertionFailed _) -> putStrLn "Assertions: On"-         _                        -> error "Assertions aren't working"+         Left (AssertionFailed _)+           | assertionsWorkingInLib -> putStrLn "Assertions: On"+         _  -> error "Assertions aren't working"      procs <- getNumCapabilities     if procs < 2 
tests/Unagi.hs view
@@ -136,7 +136,8 @@ checkDeadlocksReaderUnagi times = do   let run 0 normalRetries numRace = putStrLn $ "Lates: "++(show normalRetries)++", Races: "++(show numRace)       run n normalRetries numRace-       | (normalRetries + numRace) > (times `div` 3) = error "This test is taking too long. Please retry, and if still failing send the log to me"+       | (normalRetries + numRace) > (times `div` 2)  -- NOTE: Unagi now seems to have regular and many more lates than the other tests; I'm not sure why, but lowered the threshold.+           = error "This test is taking too long. Please retry, and if still failing send the log to me"        | otherwise = do          -- we'll kill the reader with our special exception half the time,          -- expecting that we never get our race condition on those runs:
tests/UnagiUnboxed.hs view
@@ -12,7 +12,7 @@ import Data.IORef  import Data.Int(Int8,Int16,Int32,Int64)-import Data.Word(Word,Word8,Word16,Word32,Word64)+import Data.Word import Data.Maybe import Data.Typeable @@ -20,6 +20,8 @@ import Control.Concurrent.MVar import Control.Exception import Data.Atomics.Counter.Fat++import Prelude  unagiUnboxedMain :: IO () unagiUnboxedMain = do
unagi-chan.cabal view
@@ -1,5 +1,5 @@ name:                unagi-chan-version:             0.4.0.0+version:             0.4.1.0  synopsis:            Fast concurrent queues with a Chan-like API, and more