{-# LANGUAGE CPP #-}

module Plugin.GhcTags.FileLock
  ( withFileLock
  , LockMode (..)
  ) where

import           Control.Exception
import           Control.Monad (when)

#if !defined(mingw32_HOST_OS)
import           Lukko.FLock
#else
import           Lukko.Windows
#endif

-- | 'flock' base lock (on posix) or `LockFileEx` on Windows.
--
withFileLock :: Bool -- ^ debug option
             -> FilePath -> LockMode -> (FD -> IO x) -> IO x
withFileLock :: forall x. Bool -> FilePath -> LockMode -> (FD -> IO x) -> IO x
withFileLock Bool
debug FilePath
path LockMode
mode FD -> IO x
k =
    forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
bracket
      (FilePath -> IO FD
fdOpen FilePath
path)
      (\FD
h -> FD -> IO ()
fdClose FD
h)
      forall a b. (a -> b) -> a -> b
$ \FD
h ->
        forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
bracket
          (do FD -> LockMode -> IO ()
fdLock FD
h LockMode
mode
              forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
debug (FilePath -> IO ()
putStrLn FilePath
"lock: taken"))
          (\()
_ ->
           do forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
debug (FilePath -> IO ()
putStrLn FilePath
"lock: releasing")
              FD -> IO ()
fdUnlock FD
h)
          (\()
_ -> FD -> IO x
k FD
h)