diff options
author | 2014-08-20 16:45:58 -0400 | |
---|---|---|
committer | 2014-08-20 16:45:58 -0400 | |
commit | 679d9c0027ac996eea9f41a6f0f39af436801e89 (patch) | |
tree | d98ae7ba049e2daa4a99e6bcf55054bde5e5ab4d /Utility/WinLock.hs | |
parent | 86f9d7734d0c638d4c966fd87a5d7e97759e125b (diff) |
reorganize and refactor lock code
Added a convenience Utility.LockFile that is not a windows/posix
portability shim, but still manages to cut down on the boilerplate around
locking.
This commit was sponsored by Johan Herland.
Diffstat (limited to 'Utility/WinLock.hs')
-rw-r--r-- | Utility/WinLock.hs | 74 |
1 files changed, 0 insertions, 74 deletions
diff --git a/Utility/WinLock.hs b/Utility/WinLock.hs deleted file mode 100644 index fc7c8a8a9..000000000 --- a/Utility/WinLock.hs +++ /dev/null @@ -1,74 +0,0 @@ -{- Windows lock files - - - - Copyright 2014 Joey Hess <joey@kitenet.net> - - - - License: BSD-2-clause - -} - -module Utility.WinLock ( - lockShared, - lockExclusive, - dropLock, - waitToLock, - LockHandle -) where - -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 - -{- 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. -} -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. -} -lockExclusive :: LockFile -> IO (Maybe LockHandle) -lockExclusive = openLock fILE_SHARE_NONE - -{- Windows considers just opening a file enough to lock it. This will - - create the LockFile if it does not already exist. - - - - Will fail if the file is already open with an incompatable ShareMode. - - Note that this may happen if an unrelated process, such as a virus - - scanner, even looks at the file. See http://support.microsoft.com/kb/316609 - - - - Note that createFile busy-waits to try to avoid failing when some other - - process briefly has a file open. But that would make checking locks - - much more expensive, so is not done here. Thus, the use of c_CreateFile. - - - - Also, passing Nothing for SECURITY_ATTRIBUTES ensures that the lock file - - is not inheerited by any child process. - -} -openLock :: ShareMode -> LockFile -> IO (Maybe LockHandle) -openLock sharemode f = do - h <- withTString f $ \c_f -> - c_CreateFile c_f gENERIC_READ sharemode security_attributes - oPEN_ALWAYS fILE_ATTRIBUTE_NORMAL (maybePtr Nothing) - return $ if h == iNVALID_HANDLE_VALUE - then Nothing - else Just h - where - security_attributes = maybePtr Nothing - -dropLock :: LockHandle -> IO () -dropLock = closeHandle - -{- If the initial lock fails, this is a BUSY wait, and does not - - guarentee FIFO order of waiters. In other news, Windows is a POS. -} -waitToLock :: IO (Maybe LockHandle) -> IO LockHandle -waitToLock locker = takelock - where - takelock = go =<< locker - go (Just lck) = return lck - go Nothing = do - threadDelay (500000) -- half a second - takelock |