diff options
Diffstat (limited to 'Utility')
-rw-r--r-- | Utility/LockFile.hs | 20 | ||||
-rw-r--r-- | Utility/LockFile/Posix.hs | 47 | ||||
-rw-r--r-- | Utility/LockFile/Windows.hs (renamed from Utility/WinLock.hs) | 11 |
3 files changed, 73 insertions, 5 deletions
diff --git a/Utility/LockFile.hs b/Utility/LockFile.hs new file mode 100644 index 000000000..4f0d4ba3e --- /dev/null +++ b/Utility/LockFile.hs @@ -0,0 +1,20 @@ +{- Lock files + - + - Posix and Windows lock files are extremely different. + - This module does *not* attempt to be a portability shim, it just exposes + - the native locking of the OS. + - + - Copyright 2014 Joey Hess <joey@kitenet.net> + - + - License: BSD-2-clause + -} + +{-# LANGUAGE CPP #-} + +module Utility.LockFile (module X) where + +#ifndef mingw32_HOST_OS +import Utility.LockFile.Posix as X +#else +import Utility.LockFile.Windows as X +#endif diff --git a/Utility/LockFile/Posix.hs b/Utility/LockFile/Posix.hs new file mode 100644 index 000000000..1538b491a --- /dev/null +++ b/Utility/LockFile/Posix.hs @@ -0,0 +1,47 @@ +{- Posix lock files + - + - Copyright 2014 Joey Hess <joey@kitenet.net> + - + - License: BSD-2-clause + -} + +module Utility.LockFile.Posix ( + lockShared, + lockExclusive, + dropLock, + createLockFile, + LockHandle +) where + +import System.IO +import System.Posix + +type LockFile = FilePath + +newtype LockHandle = LockHandle Fd + +-- Takes a shared lock, blocking until the lock is available. +lockShared :: Maybe FileMode -> LockFile -> IO LockHandle +lockShared = lock ReadLock + +-- Takes an exclusive lock, blocking until the lock is available. +lockExclusive :: Maybe FileMode -> LockFile -> IO LockHandle +lockExclusive = lock WriteLock + +-- The FileMode is used when creating a new lock file. +lock :: LockRequest -> Maybe FileMode -> LockFile -> IO LockHandle +lock lockreq mode lockfile = do + l <- createLockFile mode lockfile + waitToSetLock l (lockreq, AbsoluteSeek, 0, 0) + return (LockHandle l) + +-- Create and opens lock file, does not lock it. +-- Close on exec flag is set so child processes do not inherit the lock. +createLockFile :: Maybe FileMode -> LockFile -> IO Fd +createLockFile mode lockfile = do + l <- openFd lockfile ReadWrite mode defaultFileFlags + setFdOption l CloseOnExec True + return l + +dropLock :: LockHandle -> IO () +dropLock (LockHandle fd) = closeFd fd diff --git a/Utility/WinLock.hs b/Utility/LockFile/Windows.hs index fc7c8a8a9..73c248b03 100644 --- a/Utility/WinLock.hs +++ b/Utility/LockFile/Windows.hs @@ -5,7 +5,7 @@ - License: BSD-2-clause -} -module Utility.WinLock ( +module Utility.LockFile.Windows ( lockShared, lockExclusive, dropLock, @@ -17,9 +17,6 @@ import System.Win32.Types import System.Win32.File import Control.Concurrent -{- Locking is exclusive, and prevents the file from being opened for read - - or write by any other process. So for advisory locking of a file, a - - different LockFile should be used. -} type LockFile = FilePath type LockHandle = HANDLE @@ -30,7 +27,11 @@ lockShared :: LockFile -> IO (Maybe LockHandle) lockShared = openLock fILE_SHARE_READ {- Tries to take an exclusive lock on a file. Fails if another process has - - a shared or exclusive lock. -} + - a shared or exclusive lock. + - + - Note that exclusive locking also prevents the file from being opened for + - read or write by any other progess. So for advisory locking of a file's + - content, a different LockFile should be used. -} lockExclusive :: LockFile -> IO (Maybe LockHandle) lockExclusive = openLock fILE_SHARE_NONE |