lock pools to work around non-concurrency/composition safety of POSIX fcntl

This commit is contained in:
Joey Hess 2015-05-18 14:16:49 -04:00
parent af6b313456
commit 6915b71c57
8 changed files with 327 additions and 12 deletions

View file

@ -12,7 +12,6 @@ module Utility.LockFile.Posix (
tryLockExclusive,
createLockFile,
openExistingLockFile,
isLocked,
checkLocked,
getLockStatus,
dropLock,
@ -73,28 +72,23 @@ openLockFile filemode lockfile = do
setFdOption l CloseOnExec True
return l
-- Check if a file is locked, either exclusively, or with shared lock.
-- When the file doesn't exist, it's considered not locked.
isLocked :: LockFile -> IO Bool
isLocked = fromMaybe False <$$> checkLocked
-- 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 = maybe Nothing (Just . isJust) <$$> getLockStatus'
getLockStatus :: LockFile -> IO (Maybe (ProcessID, FileLock))
getLockStatus :: LockFile -> IO (Maybe ProcessID)
getLockStatus = fromMaybe Nothing <$$> getLockStatus'
getLockStatus' :: LockFile -> IO (Maybe (Maybe (ProcessID, FileLock)))
getLockStatus' :: LockFile -> IO (Maybe (Maybe ProcessID))
getLockStatus' lockfile = go =<< catchMaybeIO open
where
open = openFd lockfile ReadOnly Nothing defaultFileFlags
go Nothing = return Nothing
go (Just h) = do
ret <- getLock h (ReadLock, AbsoluteSeek, 0, 0)
v <- getLock h (ReadLock, AbsoluteSeek, 0, 0)
closeFd h
return (Just ret)
return (Just (fmap fst v))
dropLock :: LockHandle -> IO ()
dropLock (LockHandle fd) = closeFd fd

View file

@ -22,7 +22,7 @@ type LockFile = FilePath
type LockHandle = HANDLE
{- Tries to lock a file with a shared lock, which allows other processes to
- also lock it shared. Fails is the file is exclusively locked. -}
- also lock it shared. Fails if the file is exclusively locked. -}
lockShared :: LockFile -> IO (Maybe LockHandle)
lockShared = openLock fILE_SHARE_READ