ecb0d5c087
The one exception is in Utility.Daemon. As long as a process only daemonizes once, which seems reasonable, and as long as it avoids calling checkDaemon once it's already running as a daemon, the fcntl locking gotchas won't be a problem there. Annex.LockFile has it's own separate lock pool layer, which has been renamed to LockCache. This is a persistent cache of locks that persist until closed. This is not quite done; lockContent stil needs to be converted.
57 lines
1.6 KiB
Haskell
57 lines
1.6 KiB
Haskell
{- 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 (LockFile, LockMode(..))
|
|
import Utility.LockPool.LockHandle
|
|
|
|
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
|