packages feed

global-variables 1.0 → 1.0.1.0

raw patch · 3 files changed

+67/−24 lines, 3 filesdep ~stmPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependency ranges changed: stm

API changes (from Hackage documentation)

+ Data.Global: declareEmptyMVar :: Typeable a => String -> MVar a
- Data.Global: declareIORef :: Typeable a => String -> a -> (IORef a)
+ Data.Global: declareIORef :: Typeable a => String -> a -> IORef a
- Data.Global: declareMVar :: Typeable a => String -> a -> (MVar a)
+ Data.Global: declareMVar :: Typeable a => String -> a -> MVar a
- Data.Global: declareTVar :: Typeable a => String -> a -> (TVar a)
+ Data.Global: declareTVar :: Typeable a => String -> a -> TVar a

Files

global-variables.cabal view
@@ -1,5 +1,5 @@ Name:               global-variables-Version:            1.0+Version:            1.0.1.0  Synopsis:           Namespaced, global, and top-level mutable variables without                     unsafePerformIO.@@ -33,6 +33,12 @@    extends their handling significantly.    .    Examples are in the documentation of "Data.Global".+   .+   Version History:+   .+   1.0.1.0: added declareEmptyMVar and widened the stm dependency+   .+   1.0: First public release  License:            BSD3 License-file:       LICENSE@@ -46,6 +52,7 @@  Build-type:         Simple +Tested-With:        GHC == 7.0.4, GHC == 7.2.2 -- Extra files to be distributed with the package, such as examples or -- a README. -- Extra-source-files:@@ -58,7 +65,7 @@    Build-depends:      base >= 4 && < 5                     , containers >= 0.3 && < 0.5-                    , stm >= 2.1 && < 2.2+                    , stm >= 2.1 && < 2.3    Other-modules:    Data.Global.Registry 
src/Data/Global.hs view
@@ -46,6 +46,7 @@   -- * Reference of Variable Declaration Functions     declareIORef   , declareMVar+  , declareEmptyMVar   , declareTVar  ) where
src/Data/Global/Registry.hs view
@@ -13,24 +13,27 @@ ----------------------------------------------------------------------------------------------- module Data.Global.Registry (   -- * Public Interface-    declareIORef, declareMVar, declareTVar+    declareIORef, declareMVar, declareEmptyMVar, declareTVar    -- * Private Testing Interface   , lookupOrInsert   , setupRegistry ) where +import Control.Concurrent.MVar ( MVar, newMVar, newEmptyMVar, modifyMVar ) #if __GLASGOW_HASKELL__ < 702+import Control.Concurrent.MVar ( takeMVar, putMVar )+#endif+import Control.Concurrent.STM  ( TVar, newTVarIO )+#if __GLASGOW_HASKELL__ < 702 import Control.Exception       ( evaluate ) #endif-import Control.Concurrent.MVar-import Control.Concurrent.STM import Data.IORef import Data.Dynamic import Data.Map as M-import GHC.Conc (pseq)+import GHC.Conc                ( pseq )+import GHC.IO                  ( unsafePerformIO, unsafeDupablePerformIO ) -import System.IO.Unsafe   #if __GLASGOW_HASKELL__ >= 702@@ -39,6 +42,8 @@ type Registry = Map (Int,Int,String) Dynamic #endif ++ -- | Test helper setupRegistry :: IO (MVar Registry) setupRegistry = m `pseq` newMVar m@@ -64,8 +69,8 @@     -> String     -> a     -> IO (ref a)-lookupOrInsert registry new name val-    | registry `pseq` new `pseq` name `pseq` val `pseq` False = undefined+lookupOrInsert registry new name _+    | registry `pseq` new `pseq` name `pseq` False = undefined lookupOrInsert registry new name val = modifyMVar registry lkup   where     err ex got = error $ "Data.Global.Registry: Invariant violation\n"@@ -140,6 +145,18 @@   +lookupOrInsertEmptyMVar+    :: forall a. Typeable a+    => String+    -> IO (MVar a)+lookupOrInsertEmptyMVar name = lookupOrInsert globalRegistry newEmptyMVar' name (undefined :: a)+  where+    newEmptyMVar' :: a -> IO (MVar a)+    newEmptyMVar' _ = newEmptyMVar+{-# NOINLINE lookupOrInsertEmptyMVar #-}+++ lookupOrInsertTVar     :: Typeable a     => String@@ -161,11 +178,11 @@ -- pragma in order to define top-level 'IORef's. declareIORef     :: Typeable a-    => String     -- ^ The identifying name-    -> a          -- ^ The initial value of the 'IORef', it may or may not be used.-    -> (IORef a)  -- ^ A unique 'IORef' determined by @(name, typeOf val)@. Whether it refers-                  -- to the given initial value or not is unspecified.-declareIORef name val = unsafePerformIO $ lookupOrInsertIORef name val+    => String   -- ^ The identifying name+    -> a        -- ^ The initial value of the 'IORef', it may or may not be used.+    -> IORef a  -- ^ A unique 'IORef' determined by @(name, typeOf val)@. Whether it refers to+                -- the given initial value or not is unspecified.+declareIORef name val = unsafeDupablePerformIO $ lookupOrInsertIORef name val {-# NOINLINE declareIORef #-}  @@ -182,15 +199,33 @@ -- pragma in order to define top-level 'MVar's. declareMVar     :: Typeable a-    => String    -- ^ The identifying name-    -> a         -- ^ The initial value of the 'MVar', it may or may not be used.-    -> (MVar a)  -- ^ A unique 'MVar' determined by @(name, typeOf val)@. Whether it refers to-                 -- the given initial value or not is unspecified.-declareMVar name val = unsafePerformIO $ lookupOrInsertMVar name val+    => String  -- ^ The identifying name+    -> a       -- ^ The initial value of the 'MVar', it may or may not be used.+    -> MVar a  -- ^ A unique 'MVar' determined by @(name, typeOf val)@. Whether it refers to+               -- the given initial value or not is unspecified.+declareMVar name val = unsafeDupablePerformIO $ lookupOrInsertMVar name val {-# NOINLINE declareMVar #-}  +-- | @declareEmptyMVar name@ maps a variable name to an 'MVar'. Calling it multiple times with+-- the same @name@ and type of the expected 'MVar' will always return the same 'MVar'.+--+-- @+-- someVar :: MVar Int+-- someVar = declareEmptyMVar \"my-global-some-var\"+-- @+--+-- Note, there is /no/ need to use 'unsafePerformIO' or to add a @{-\# NOINLINE someVar \#-}@+-- pragma in order to define top-level 'MVar's.+declareEmptyMVar+    :: Typeable a+    => String  -- ^ The identifying name+    -> MVar a  -- ^ A unique 'MVar' determined by @(name, typeOf val)@. Whether it is still+               -- empty depends on the rest of the program.+declareEmptyMVar name = unsafeDupablePerformIO $ lookupOrInsertEmptyMVar name+{-# NOINLINE declareEmptyMVar #-} + -- | @declareTVar name val@ maps a variable name to an 'TVar'. Calling it multiple times with the same -- @name@ and type of 'val' will always return the same 'TVar'. --@@ -203,9 +238,9 @@ -- pragma in order to define top-level 'TVar's. declareTVar     :: Typeable a-    => String    -- ^ The identifying name-    -> a         -- ^ The initial value of the 'TVar', it may or may not be used.-    -> (TVar a)  -- ^ A unique 'TVar' determined by @(name, typeOf val)@. Whether it refers to-                 -- the given initial value or not is unspecified.-declareTVar name val = unsafePerformIO $ lookupOrInsertTVar name val+    => String  -- ^ The identifying name+    -> a       -- ^ The initial value of the 'TVar', it may or may not be used.+    -> TVar a  -- ^ A unique 'TVar' determined by @(name, typeOf val)@. Whether it refers to+               -- the given initial value or not is unspecified.+declareTVar name val = unsafeDupablePerformIO $ lookupOrInsertTVar name val {-# NOINLINE declareTVar #-}