-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | This package provides access to platform dependent file locking APIs:
--   
--   <ul>
--   <li><a>Open file descriptor locking</a> on Linux
--   (<a>Lukko.OFD</a>)</li>
--   <li>BSD-style <tt>flock(2)</tt> locks on UNIX platforms
--   (<a>Lukko.FLock</a>)</li>
--   <li>Windows locking via <a>LockFileEx</a> (<a>Lukko.Windows</a>)</li>
--   <li>No-op locking, which throws exceptions (<a>Lukko.NoOp</a>)</li>
--   <li><a>Lukko</a> module exports the best option for the target
--   platform with uniform API.</li>
--   </ul>
--   
--   There are alternative file locking packages:
--   
--   <ul>
--   <li><a>GHC.IO.Handle.Lock</a> in <tt>base &gt;= 4.10</tt> is good
--   enough for most use cases. However, uses only <a>Handle</a>s so these
--   locks cannot be used for intra-process locking. (You should use e.g.
--   <a>MVar</a> in addition).</li>
--   <li><a>filelock</a> doesn't support OFD locking.</li>
--   </ul>
--   
--   <i>Lukko</i> means lock in Finnish.
--   
--   Submodules <a>Lukko.OFD</a>, <a>Lukko.Windows</a> etc are available
--   based on following conditions.
--   
--   <pre>
--   if os(windows)
--     cpp-options: -DHAS_WINDOWS_LOCK
--   
--   elif (os(linux) &amp;&amp; flag(ofd-locking))
--     cpp-options: -DHAS_OFD_LOCKING
--     cpp-options: -DHAS_FLOCK
--   
--   elif !(os(solaris) || os(aix))
--     cpp-options: -DHAS_FLOCK
--   </pre>
--   
--   <a>Lukko.FLock</a> is available on not (Windows or Solaris or AIX).
--   <a>Lukko.NoOp</a> is always available.
@package lukko
@version 0.1.2


-- | File locking via BSD-style <tt>flock(2)</tt>.
module Lukko.FLock

-- | Exception thrown by <tt>hLock</tt> on non-Windows platforms that don't
--   support <tt>flock</tt>.
data FileLockingNotSupported
FileLockingNotSupported :: FileLockingNotSupported

-- | A constants specifying whether file locking is supported.
fileLockingSupported :: Bool

-- | A type level <a>fileLockingSupported</a>.
type FileLockingSupported = 'True

-- | Potentially availble lock methods.
data FileLockingMethod

-- | open file descriptor locking
MethodOFD :: FileLockingMethod

-- | BSD <tt>flock</tt>
MethodFLock :: FileLockingMethod

-- | Windows locking
MethodWindows :: FileLockingMethod

-- | No-Op (throws <a>FileLockingNotSupported</a>)
MethodNoOp :: FileLockingMethod

-- | A constant specifying this method
fileLockingMethod :: FileLockingMethod

-- | Indicates a mode in which a file should be locked.
data LockMode
SharedLock :: LockMode
ExclusiveLock :: LockMode

-- | Opaque <i>file descriptor</i>
--   
--   This is a wrapper over <a>CInt</a>
data FD

-- | Open file to be used for locking.
--   
--   <pre>
--   open(path, O_RDWR | O_CREAT);
--   </pre>
fdOpen :: FilePath -> IO FD

-- | Close lock file.
--   
--   <pre>
--   close(fd);
--   </pre>
fdClose :: FD -> IO ()

-- | Lock using BSD-style locks.
fdLock :: FD -> LockMode -> IO ()

-- | Try to lock using BSD-style locks.
fdTryLock :: FD -> LockMode -> IO Bool

-- | Unlock using BSD-style locks.
fdUnlock :: FD -> IO ()

-- | Lock using BSD-style locks.
hLock :: Handle -> LockMode -> IO ()

-- | Try to lock using BSD-style locks.
hTryLock :: Handle -> LockMode -> IO Bool

-- | Unlock using BSD-style locks.
hUnlock :: Handle -> IO ()


-- | Non-operating locks.
--   
--   All functions throw <tt>FileLockingNotImplemented</tt>.
module Lukko.NoOp

-- | Exception thrown by <tt>hLock</tt> on non-Windows platforms that don't
--   support <tt>flock</tt>.
data FileLockingNotSupported
FileLockingNotSupported :: FileLockingNotSupported

-- | A constants specifying whether file locking is supported.
fileLockingSupported :: Bool

-- | A type level <a>fileLockingSupported</a>.
type FileLockingSupported = 'False

-- | Potentially availble lock methods.
data FileLockingMethod

-- | open file descriptor locking
MethodOFD :: FileLockingMethod

-- | BSD <tt>flock</tt>
MethodFLock :: FileLockingMethod

-- | Windows locking
MethodWindows :: FileLockingMethod

-- | No-Op (throws <a>FileLockingNotSupported</a>)
MethodNoOp :: FileLockingMethod

-- | A constant specifying this method
fileLockingMethod :: FileLockingMethod

-- | Indicates a mode in which a file should be locked.
data LockMode
SharedLock :: LockMode
ExclusiveLock :: LockMode

-- | Opaque <i>file descriptor</i>
--   
--   This is a wrapper over <a>CInt</a>
data FD

-- | Open file to be used for locking.
--   
--   <pre>
--   open(path, O_RDWR | O_CREAT);
--   </pre>
fdOpen :: FilePath -> IO FD

-- | Close lock file.
--   
--   <pre>
--   close(fd);
--   </pre>
fdClose :: FD -> IO ()

-- | No-op implementation.
fdLock :: FD -> LockMode -> IO ()

-- | No-op implementation
fdTryLock :: FD -> LockMode -> IO Bool

-- | No-op implementation.
fdUnlock :: FD -> IO ()

-- | No-op implementation.
hLock :: Handle -> LockMode -> IO ()

-- | No-op implementation
hTryLock :: Handle -> LockMode -> IO Bool

-- | No-op implementation.
hUnlock :: Handle -> IO ()


-- | Linux open file descriptor locking.
--   
--   
--   <a>https://www.gnu.org/software/libc/manual/html_node/Open-File-Description-Locks.html</a>
--   
--   We prefer this over BSD locking (e.g. flock) since the latter appears
--   to break in some NFS configurations. Note that we intentionally do not
--   try to use ordinary POSIX file locking due to its peculiar semantics
--   under multi-threaded environments.
module Lukko.OFD

-- | Exception thrown by <tt>hLock</tt> on non-Windows platforms that don't
--   support <tt>flock</tt>.
data FileLockingNotSupported
FileLockingNotSupported :: FileLockingNotSupported

-- | A constants specifying whether file locking is supported.
fileLockingSupported :: Bool

-- | A type level <a>fileLockingSupported</a>.
type FileLockingSupported = 'True

-- | Potentially availble lock methods.
data FileLockingMethod

-- | open file descriptor locking
MethodOFD :: FileLockingMethod

-- | BSD <tt>flock</tt>
MethodFLock :: FileLockingMethod

-- | Windows locking
MethodWindows :: FileLockingMethod

-- | No-Op (throws <a>FileLockingNotSupported</a>)
MethodNoOp :: FileLockingMethod

-- | A constant specifying this method
fileLockingMethod :: FileLockingMethod

-- | Indicates a mode in which a file should be locked.
data LockMode
SharedLock :: LockMode
ExclusiveLock :: LockMode

-- | Opaque <i>file descriptor</i>
--   
--   This is a wrapper over <a>CInt</a>
data FD

-- | Open file to be used for locking.
--   
--   <pre>
--   open(path, O_RDWR | O_CREAT);
--   </pre>
fdOpen :: FilePath -> IO FD

-- | Close lock file.
--   
--   <pre>
--   close(fd);
--   </pre>
fdClose :: FD -> IO ()

-- | Lock using OFD locks.
fdLock :: FD -> LockMode -> IO ()

-- | Try to lock using OFD locks.
fdTryLock :: FD -> LockMode -> IO Bool

-- | Unlock using OFD locks.
fdUnlock :: FD -> IO ()

-- | Lock using OFD locks.
hLock :: Handle -> LockMode -> IO ()

-- | Try to lock using OFD locks.
hTryLock :: Handle -> LockMode -> IO Bool

-- | Unlock using OFD locks.
hUnlock :: Handle -> IO ()
instance GHC.Internal.Foreign.Storable.Storable Lukko.OFD.FLock


-- | Open <a>Handle</a> based locking
module Lukko

-- | Exception thrown by <tt>hLock</tt> on non-Windows platforms that don't
--   support <tt>flock</tt>.
data FileLockingNotSupported
FileLockingNotSupported :: FileLockingNotSupported

-- | A constants specifying whether file locking is supported.
fileLockingSupported :: Bool

-- | A type level <a>fileLockingSupported</a>.
type FileLockingSupported = 'True

-- | Potentially availble lock methods.
data FileLockingMethod

-- | open file descriptor locking
MethodOFD :: FileLockingMethod

-- | BSD <tt>flock</tt>
MethodFLock :: FileLockingMethod

-- | Windows locking
MethodWindows :: FileLockingMethod

-- | No-Op (throws <a>FileLockingNotSupported</a>)
MethodNoOp :: FileLockingMethod

-- | A constant specifying this method
fileLockingMethod :: FileLockingMethod

-- | Indicates a mode in which a file should be locked.
data LockMode
SharedLock :: LockMode
ExclusiveLock :: LockMode

-- | Opaque <i>file descriptor</i>
--   
--   An <tt>int</tt> / <tt>CInt</tt> on unix systems, and <tt>HANDLE</tt>
--   on windows.
type FD = FD

-- | Open file to be used for locking.
fdOpen :: FilePath -> IO FD

-- | Close lock file.
fdClose :: FD -> IO ()

-- | Like <a>hLock</a>, but work on "raw" file descriptor, as handled by
--   <a>fdOpen</a> and <a>fdClose</a>.
fdLock :: FD -> LockMode -> IO ()

-- | Non-blocking version of <a>fdLock</a>.
fdTryLock :: FD -> LockMode -> IO Bool

-- | Release a lock taken with <a>fdLock</a> or <a>fdTryLock</a>.
fdUnlock :: FD -> IO ()

-- | Convert GHC <a>Handle</a> to lukko <a>FD</a>.
handleToFd :: Handle -> IO FD

-- | If a <a>Handle</a> references a file descriptor, attempt to lock
--   contents of the underlying file in appropriate mode. If the file is
--   already locked in incompatible mode, this function blocks until the
--   lock is established. The lock is automatically released upon closing a
--   <a>Handle</a>.
--   
--   Things to be aware of:
--   
--   1) This function may block inside a C call. If it does, in order to be
--   able to interrupt it with asynchronous exceptions and/or for other
--   threads to continue working, you MUST use threaded version of the
--   runtime system.
--   
--   2) The implementation uses <tt>LockFileEx</tt> on Windows, <i>open
--   file descriptor</i> locks on Linux, and <tt>flock</tt> otherwise,
--   hence all of their caveats also apply here.
--   
--   3) On non-Windows plaftorms that don't support <tt>flock</tt> (e.g.
--   Solaris) this function throws <tt>FileLockingNotImplemented</tt>. We
--   deliberately choose to not provide <tt>fcntl</tt> based locking
--   instead because of its broken semantics.
hLock :: Handle -> LockMode -> IO ()

-- | Non-blocking version of <a>hLock</a>.
hTryLock :: Handle -> LockMode -> IO Bool

-- | Release a lock taken with <a>hLock</a> or <a>hTryLock</a>.
hUnlock :: Handle -> IO ()
