Permalink
Browse files

document

  • Loading branch information...
1 parent 8e62597 commit 67e9190b1d61f0ed359e4c2c057ebff84db98562 @kmcallister committed Nov 2, 2011
Showing with 29 additions and 4 deletions.
  1. +4 −1 README
  2. +4 −0 System/GlobalLock.hs
  3. +8 −0 System/GlobalLock/Internal.hs
  4. +13 −3 global-lock.cabal
View
5 README
@@ -1,4 +1,7 @@
-FIXME
+global-lock provides a single global lock for Haskell code, implemented without
+unsafePerformIO. You can use this, for example, to protect a thread-unsafe C
+library. global-lock is usable as-is, or as a template for including a similar
+lock in your own Haskell project.
Documentation is hosted at http://hackage.haskell.org/package/global-lock
View
@@ -1,3 +1,4 @@
+-- | Provides a single global lock for @'IO'@ actions.
module System.GlobalLock
( lock
) where
@@ -6,5 +7,8 @@ import Control.Concurrent.MVar
import System.GlobalLock.Internal
+-- | Take the global lock for the duration of an @'IO'@ action.
+--
+-- Two actions executed via @'lock'@ will never run simultaneously.
lock :: IO a -> IO a
lock act = get >>= flip withMVar (const act)
@@ -1,5 +1,9 @@
{-# LANGUAGE
ForeignFunctionInterface #-}
+
+-- | Internals of global locking.
+--
+-- Use with caution!
module System.GlobalLock.Internal
( get
) where
@@ -9,6 +13,7 @@ import Foreign.C
import Control.Monad
import Control.Concurrent.MVar
+
{- Importing c_get_global with 'unsafe' decreases locking latency by
about 50%. It's okay because that function just reads a C static
global.
@@ -26,14 +31,17 @@ foreign import ccall unsafe "hs_globalzmlock_get_global"
foreign import ccall "hs_globalzmlock_set_global"
c_set_global :: Ptr () -> IO CInt
+
set :: IO ()
set = do
mv <- newMVar ()
ptr <- newStablePtr mv
ret <- c_set_global (castStablePtrToPtr ptr)
when (ret == 0) $
+ -- The variable was already set; our StablePtr is unused.
freeStablePtr ptr
+-- | Get the single @'MVar'@ used for global locking.
get :: IO (MVar ())
get = do
p <- c_get_global
View
@@ -2,14 +2,24 @@ name: global-lock
version: 0.1
license: BSD3
license-file: LICENSE
-synopsis: FIXME
-category: FIXME
+synopsis: A global lock implemented without unsafePerformIO
+category: System, Concurrency
author: Keegan McAllister <mcallister.keegan@gmail.com>
maintainer: Keegan McAllister <mcallister.keegan@gmail.com>
build-type: Simple
cabal-version: >=1.6
description:
- FIXME
+ This library provides a single global lock. You can use it, for example,
+ to protect a thread-unsafe C library.
+ .
+ The implementation does not use @unsafePerformIO@. It should be safe
+ against GHC bugs such as <http://hackage.haskell.org/trac/ghc/ticket/5558>.
+ .
+ You can use this library as-is, or as a template for including a similar
+ lock in your own Haskell project.
+ .
+ This library requires that the C compiler invoked by Cabal is GCC 4.1 or
+ newer.
extra-source-files:
README

0 comments on commit 67e9190

Please sign in to comment.