summaryrefslogtreecommitdiff
path: root/Utility/LockPool/Windows.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/Windows.hs
parent6a318cf0c050f9fa7959874bf0eb8f1105ef0a4b (diff)
lock pools to work around non-concurrency/composition safety of POSIX fcntl
Diffstat (limited to 'Utility/LockPool/Windows.hs')
-rw-r--r--Utility/LockPool/Windows.hs49
1 files changed, 49 insertions, 0 deletions
diff --git a/Utility/LockPool/Windows.hs b/Utility/LockPool/Windows.hs
new file mode 100644
index 000000000..2537863e2
--- /dev/null
+++ b/Utility/LockPool/Windows.hs
@@ -0,0 +1,49 @@
+{- Windows lock files, using lock pools.
+ -
+ - Copyright 2015 Joey Hess <id@joeyh.name>
+ -
+ - License: BSD-2-clause
+ -}
+
+module Utility.LockPool.Windows (
+ LockHandle,
+ lockShared,
+ lockExclusive,
+ dropLock,
+ waitToLock,
+) where
+
+import qualified Utility.LockFile.Windows as F
+import qualified Utility.LockPool.STM as P
+import Utility.LockPool.LockHandle
+import Utility.LockPool.STM (LockPool, LockFile, LockMode(..))
+import Utility.Monad
+
+import Control.Concurrent.STM
+import System.IO
+import Data.Maybe
+import Control.Applicative
+import Prelude
+
+{- Tries to lock a file with a shared lock, which allows other processes to
+ - also lock it shared. Fails if the file is exclusively locked. -}
+lockShared :: LockFile -> IO (Maybe LockHandle)
+lockShared file = tryMakeLockHandle
+ (P.tryTakeLock P.lockPool file LockShared)
+ (F.lockShared mode file)
+
+{- Tries to take an exclusive lock on a file. Fails if another process has
+ - a shared or exclusive lock.
+ -
+ - Note that exclusive locking also prevents the file from being opened for
+ - read or write by any other process. So for advisory locking of a file's
+ - content, a separate LockFile should be used. -}
+lockExclusive :: LockFile -> IO (Maybe LockHandle)
+lockExclusive file = tryMakeLockHandle
+ (P.tryTakeLock P.lockPool file LockExclusive)
+ (F.lockExclusive file)
+
+{- 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 = F.waitToLock