aboutsummaryrefslogtreecommitdiff
path: root/Utility/LockPool/Posix.hs
diff options
context:
space:
mode:
authorGravatar Joey Hess <joeyh@joeyh.name>2015-05-18 14:16:49 -0400
committerGravatar Joey Hess <joeyh@joeyh.name>2015-05-18 15:57:17 -0400
commit94a3e606fb31150c969d63790ec1ef870f413cc1 (patch)
tree566860a856e7d064e18de4c3a8a2e561377caf3c /Utility/LockPool/Posix.hs
parent6a318cf0c050f9fa7959874bf0eb8f1105ef0a4b (diff)
lock pools to work around non-concurrency/composition safety of POSIX fcntl
Diffstat (limited to 'Utility/LockPool/Posix.hs')
-rw-r--r--Utility/LockPool/Posix.hs59
1 files changed, 59 insertions, 0 deletions
diff --git a/Utility/LockPool/Posix.hs b/Utility/LockPool/Posix.hs
new file mode 100644
index 000000000..e460272f2
--- /dev/null
+++ b/Utility/LockPool/Posix.hs
@@ -0,0 +1,59 @@
+{- Posix lock files, using lock pools.
+ -
+ - Copyright 2015 Joey Hess <id@joeyh.name>
+ -
+ - License: BSD-2-clause
+ -}
+
+module Utility.LockPool.Posix (
+ LockHandle,
+ lockShared,
+ lockExclusive,
+ tryLockExclusive,
+ checkLocked,
+ getLockStatus,
+ dropLock,
+ checkSaneLock,
+) where
+
+import qualified Utility.LockFile.Posix as F
+import qualified Utility.LockPool.STM as P
+import Utility.LockPool.STM (LockPool, LockFile, LockMode(..))
+import Utility.LockPool.LockHandle
+import Utility.Monad
+
+import Control.Concurrent.STM
+import System.IO
+import System.Posix
+import Data.Maybe
+import Control.Applicative
+import Prelude
+
+-- Takes a shared lock, blocking until the lock is available.
+lockShared :: Maybe FileMode -> LockFile -> IO LockHandle
+lockShared mode file = makeLockHandle
+ (P.waitTakeLock P.lockPool file LockShared)
+ (F.lockShared mode file)
+
+lockExclusive :: Maybe FileMode -> LockFile -> IO LockHandle
+lockExclusive mode file = makeLockHandle
+ (P.waitTakeLock P.lockPool file LockExclusive)
+ (F.lockExclusive mode file)
+
+tryLockExclusive :: Maybe FileMode -> LockFile -> IO (Maybe LockHandle)
+tryLockExclusive mode file = tryMakeLockHandle
+ (P.tryTakeLock P.lockPool file LockExclusive)
+ (F.tryLockExclusive mode file)
+
+-- Returns Nothing when the file doesn't exist, for cases where
+-- that is different from it not being locked.
+checkLocked :: LockFile -> IO (Maybe Bool)
+checkLocked file = P.getLockStatus P.lockPool file (pure True)
+ (F.checkLocked file)
+
+getLockStatus :: LockFile -> IO (Maybe ProcessID)
+getLockStatus file = P.getLockStatus P.lockPool file getProcessID
+ (F.getLockStatus file)
+
+checkSaneLock :: LockFile -> LockHandle -> IO Bool
+checkSaneLock lockfile (LockHandle _ fh) = F.checkSaneLock lockfile fh