module System.Posix.FileLock (lock,unlock,withLock,FileLock,LockType(..)) where
import Control.Exception (bracket)
import Control.Monad.IO.Class (MonadIO(..), liftIO)
import qualified System.Posix.Files as Posix
import qualified System.Posix.IO as Posix
import qualified System.Posix.Types as Posix
import System.IO
data FileLock = FileLock Posix.Fd Posix.FileLock
data LockType = ReadLock | WriteLock deriving (Eq, Show, Read)
withLock :: (MonadIO m) => FilePath -> LockType -> IO a -> m a
withLock pth t x = liftIO $ bracket (lock pth t) unlock (const x)
lock :: (MonadIO m) => FilePath -> LockType -> m FileLock
lock pth t = liftIO $ do
fd <- Posix.openFd pth om mode Posix.defaultFileFlags
Posix.waitToSetLock fd (req, AbsoluteSeek, 0, 0)
return $ FileLock fd (Posix.Unlock, AbsoluteSeek, 0, 0)
where
mode =
Just $ Posix.unionFileModes Posix.ownerReadMode Posix.ownerWriteMode
om = case t of
ReadLock -> Posix.ReadOnly
WriteLock -> Posix.WriteOnly
req = case t of
ReadLock -> Posix.ReadLock
WriteLock -> Posix.WriteLock
unlock :: (MonadIO m) => FileLock -> m ()
unlock (FileLock fd lck) = liftIO $ do
Posix.setLock fd lck
Posix.closeFd fd