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


-- | Cross-platform abstraction for system semaphores
--   
--   Cross-platform semaphores for managing resources across processes,
--   abstracting over Win32 named semaphores on Windows and Unix domain
--   sockets on POSIX.
@package semaphore-compat
@version 2.0.1


-- | FFI glue code for Unix domain sockets.
module System.Semaphore.Internal.DomainSocket
connectDomainSocket :: FilePath -> IO Fd

-- | Open a socket in non blocking mode (O_NONBLOCK)
listenDomainSocket :: FilePath -> IO Fd

-- | Block until either a client connects or the cancel fd is written to.
--   
--   Relies on cooperative cancellation implemented in hs_poll_accept using
--   <tt>poll(2)</tt> + <tt>accept(2)</tt> via safe FFI to avoid GHC #27110
--   and #27113.
--   
--   Must be called from a masked context. The caller is responsible for
--   installing an exception handler that closes all 3 fds (inputs and
--   outputs).
pollAcceptSocket :: Fd -> Fd -> IO AcceptResult

-- | Result of <a>pollAcceptSocket</a>.
data AcceptResult

-- | A client connected; here is the fd.
AcceptedFd :: Fd -> AcceptResult

-- | The cancel pipe was signalled.
AcceptCancelled :: AcceptResult

-- | Read a single byte from a file descriptor. Throws an EOF
--   <a>IOError</a> if the peer has disconnected.
fdReadByte :: HasCallStack => Fd -> IO Word8

-- | Write a single byte to a file descriptor.
fdWriteByte :: HasCallStack => Fd -> Word8 -> IO ()

-- | Shut down a socket for both reading and writing. A concurrent
--   <a>fdReadByte</a> on the same fd will return immediately Used to
--   cancel threads blocked in read()
fdShutdown :: Fd -> IO ()


-- | The Unix domain socket server backing the POSIX semaphore
--   implementation.
--   
--   The server manages a shared token pool and accepts multiple client
--   connections, each served on its own thread.
--   
--   Protocol (SOCK_STREAM, one byte per command):
--   
--   "-" Wait (blocking acquire). Decrements semaphore; replies ".". "?"
--   Try-wait. Decrements if positive and replies "."; otherwise replies
--   "!". "+" Release. Increments pool; replies ".". Rejected with "!" if
--   myCount &lt;= 0 (client has not acquired any tokens on this
--   connection).
--   
--   Unrecognised bytes are rejected with <a>RspFail</a>.
--   
--   Per-connection token tracking: the server counts tokens held by each
--   connection (myCount). On disconnect (EOF / ResourceVanished) held
--   tokens are returned to the pool, so a crashing client cannot leak
--   tokens.
--   
--   Connections are tied to a token, so each token (obtained by
--   <tt>waitOnSemaphore</tt>) has its own connection.
module System.Semaphore.Internal.Posix.Server

-- | Run the server accept loop on a listening socket until cancellation is
--   signalled via the cancel pipe. All accepted connections are served on
--   child threads, which are cleaned up before this returns.
serverLoop :: TVar Int -> Fd -> Fd -> IO ()
pattern CmdWait :: Word8
pattern CmdTryWait :: Word8
pattern CmdRelease :: Word8
pattern RspOk :: Word8
pattern RspFail :: Word8


-- | Semaphore protocol version and versioned semaphore identifiers.
module System.Semaphore.Internal.Version

-- | A semaphore name: a protocol version and an unversioned name string.
data SemaphoreName
SemaphoreName :: SemaphoreProtocolVersion -> String -> SemaphoreName
[semaphoreProtocolVersion] :: SemaphoreName -> SemaphoreProtocolVersion
[unversionedSemaphoreNameString] :: SemaphoreName -> String

-- | The identifier string of a semaphore: a serialised
--   <a>SemaphoreName</a> used for inter-process communication (e.g. as a
--   command line argument).
--   
--   The specific format of this name string depends on the <b>protocol</b>
--   version:
--   
--   <ul>
--   <li>For version 1, this is the unadorned semaphore name.</li>
--   <li>For version <tt>N &gt;= 2</tt>, the semaphore name is prefixed
--   with <tt>v&lt;N&gt;-</tt>.</li>
--   </ul>
type SemaphoreIdentifier = String

-- | The semaphore protocol version currently being used.
--   
--   The version tracks the IPC mechanism, not the library version:
--   
--   <ul>
--   <li><b>POSIX:</b> 2 (domain sockets, replacing v1 system
--   semaphores).</li>
--   <li><b>Windows:</b> 1 (Win32 named semaphores, unchanged from
--   v1).</li>
--   <li><b>Unsupported platforms:</b> 0 (no compatible IPC backend).</li>
--   </ul>
newtype SemaphoreProtocolVersion
SemaphoreProtocolVersion :: Int -> SemaphoreProtocolVersion
[getSemaphoreProtocolVersion] :: SemaphoreProtocolVersion -> Int

-- | Errors that can occur when creating or opening a semaphore.
data SemaphoreError

-- | Can't create a semaphore: a semaphore with this name already exists.
SemaphoreAlreadyExists :: SemaphoreIdentifier -> SemaphoreError
[semaphoreErrorIdentifier] :: SemaphoreError -> SemaphoreIdentifier

-- | Can't open a semaphore: no semaphore with this name exists.
SemaphoreDoesNotExist :: SemaphoreIdentifier -> SemaphoreError
[semaphoreErrorIdentifier] :: SemaphoreError -> SemaphoreIdentifier

-- | Protocol version incompatibility: the semaphore identifier uses a
--   different protocol version than the library is currently using.
SemaphoreIncompatibleVersion :: SemaphoreProtocolVersion -> SemaphoreProtocolVersion -> SemaphoreError
[semaphoreErrorActualVersion] :: SemaphoreError -> SemaphoreProtocolVersion
[semaphoreErrorExpectedVersion] :: SemaphoreError -> SemaphoreProtocolVersion

-- | An <a>IOException</a> was raised when creating or opening the
--   semaphore.
SemaphoreOtherError :: IOException -> SemaphoreError
[semaphoreOtherError] :: SemaphoreError -> IOException

-- | The protocol version used on this host platform with this version of
--   <tt>semaphore-compat</tt>.
--   
--   See <a>SemaphoreProtocolVersion</a>.
semaphoreVersion :: SemaphoreProtocolVersion

-- | The serialised identifier of a <a>SemaphoreName</a> for inter-process
--   communication.
--   
--   See <a>SemaphoreIdentifier</a> for more information.
semaphoreIdentifier :: SemaphoreName -> SemaphoreIdentifier

-- | Parse a <a>SemaphoreIdentifier</a> into a <a>SemaphoreName</a>.
--   
--   Returns <tt>Nothing</tt> for unversioned strings (which should be
--   treated as v1 by the caller's compatibility logic).
parseSemaphoreIdentifier :: SemaphoreIdentifier -> Maybe SemaphoreName

-- | The socket file path for a semaphore.
getSemaphoreSocketPath :: SemaphoreName -> IO FilePath

-- | Convert an <a>Int</a> to a base-62 string (digits
--   <tt>0</tt>–<tt>9</tt>, <tt>a</tt>–<tt>z</tt>, <tt>A</tt>–<tt>Z</tt>).
iToBase62 :: Int -> String
instance GHC.Internal.Classes.Eq System.Semaphore.Internal.Version.SemaphoreError
instance GHC.Internal.Classes.Eq System.Semaphore.Internal.Version.SemaphoreName
instance GHC.Internal.Classes.Eq System.Semaphore.Internal.Version.SemaphoreProtocolVersion
instance GHC.Internal.Exception.Type.Exception System.Semaphore.Internal.Version.SemaphoreError
instance GHC.Internal.Classes.Ord System.Semaphore.Internal.Version.SemaphoreProtocolVersion
instance GHC.Internal.Show.Show System.Semaphore.Internal.Version.SemaphoreError
instance GHC.Internal.Show.Show System.Semaphore.Internal.Version.SemaphoreName
instance GHC.Internal.Show.Show System.Semaphore.Internal.Version.SemaphoreProtocolVersion


-- | POSIX backend: semaphores implemented on top of Unix domain sockets.
module System.Semaphore.Internal.Posix
data ClientSemaphore
ClientSemaphore :: SemaphoreName -> FilePath -> ClientSemaphore
[clientSemaphoreName] :: ClientSemaphore -> SemaphoreName
[semSocketPath] :: ClientSemaphore -> FilePath
data ServerSemaphore
ServerSemaphore :: ClientSemaphore -> ThreadId -> TVar Int -> MVar ServerState -> ServerSemaphore
[serverClientSemaphore] :: ServerSemaphore -> ClientSemaphore
[serverThreadId] :: ServerSemaphore -> ThreadId
[serverPool] :: ServerSemaphore -> TVar Int
[serverState] :: ServerSemaphore -> MVar ServerState
newtype SemaphoreToken
SemaphoreToken :: MVar Fd -> SemaphoreToken
[tokenFdLock] :: SemaphoreToken -> MVar Fd
waitOnSemaphore :: HasCallStack => ClientSemaphore -> IO SemaphoreToken
tryWaitOnSemaphore :: HasCallStack => ClientSemaphore -> IO (Maybe SemaphoreToken)
releaseSemaphoreToken :: HasCallStack => SemaphoreToken -> IO ()
destroyClientSemaphore :: ClientSemaphore -> IO ()
destroyServerSemaphore :: ServerSemaphore -> IO ()
getSemaphoreValue :: ServerSemaphore -> IO Int
create_sem :: SemaphoreName -> Int -> IO (Either SemaphoreError ServerSemaphore)
open_sem_raw :: SemaphoreName -> IO (Either SemaphoreError ClientSemaphore)
get_time_seed :: IO Int


-- | Platform-independent internal API.
module System.Semaphore.Internal

-- | A client-side semaphore: the handle a jobclient uses to acquire and
--   release tokens from a semaphore created by a jobserver.
--   
--   Retrieve the underlying name with <a>clientSemaphoreName</a>.
newtype ClientSemaphore
ClientSemaphore :: ClientSemaphore -> ClientSemaphore

-- | A server-side semaphore: a <a>ClientSemaphore</a> together with the
--   book-keeping needed to track resource usage by all clients.
--   
--   Retrieve the corresponding client semaphore with
--   <a>serverClientSemaphore</a>.
newtype ServerSemaphore
ServerSemaphore :: ServerSemaphore -> ServerSemaphore

-- | A held semaphore token: evidence of one unit of resource acquired from
--   a semaphore.
--   
--   Use <a>releaseSemaphoreToken</a> or <tt>withSemaphoreToken</tt> to
--   ensure prompt release of semaphore tokens.
--   
--   Platform-dependent behaviour:
--   
--   <ul>
--   <li>On POSIX, if all references to a <a>SemaphoreToken</a> are dropped
--   without being released, a finalizer returns the token to the
--   semaphore.</li>
--   <li>On Windows, tokens held by a crashed client are permanently
--   lost.</li>
--   </ul>
newtype SemaphoreToken
SemaphoreToken :: SemaphoreToken -> SemaphoreToken

-- | Retrieve the underlying name of a client-side semaphore.
clientSemaphoreName :: ClientSemaphore -> SemaphoreName

-- | Retrieve the client-side semaphore corresponding to a server-side
--   semaphore.
serverClientSemaphore :: ServerSemaphore -> ClientSemaphore

-- | Acquire a token from the semaphore, blocking until one is available.
--   
--   The returned <a>SemaphoreToken</a> must be released with
--   <a>releaseSemaphoreToken</a>. For prompt and predictable release of
--   resources, callers should use <a>withSemaphoreToken</a> or
--   <a>releaseSemaphoreToken</a>.
--   
--   This operation is interruptible: it can be cancelled by
--   <a>throwTo</a>, <a>killThread</a>, etc. If interrupted, any
--   transiently acquired token is automatically returned.
waitOnSemaphore :: HasCallStack => ClientSemaphore -> IO SemaphoreToken

-- | Try to acquire a token from the semaphore without blocking.
--   
--   Returns <tt>Just token</tt> if a token was available, <tt>Nothing</tt>
--   otherwise.
--   
--   This is <b>not</b> an interruptible operation, but that should not be
--   a problem: this function is not expected to block for long, as the
--   server is supposed to respond immediately.
tryWaitOnSemaphore :: HasCallStack => ClientSemaphore -> IO (Maybe SemaphoreToken)

-- | Release a semaphore token, returning it to the pool.
--   
--   Idempotent: a second call on the same token is a safe no-op.
releaseSemaphoreToken :: HasCallStack => SemaphoreToken -> IO ()

-- | Destroy a client-side semaphore.
--   
--   This is an idempotent operation: double calls to
--   <a>destroyClientSemaphore</a> do not cause any problems.
destroyClientSemaphore :: ClientSemaphore -> IO ()

-- | Destroy a server-side semaphore.
--   
--   Idempotent. Not interruptible.
destroyServerSemaphore :: ServerSemaphore -> IO ()

-- | Query the current semaphore value (how many tokens it has available).
--   
--   This is mainly for debugging use, as it is easy to introduce race
--   conditions when nontrivial program logic depends on the value returned
--   by this function.
getSemaphoreValue :: ServerSemaphore -> IO Int
create_sem :: SemaphoreName -> Int -> IO (Either SemaphoreError ServerSemaphore)
open_sem_raw :: SemaphoreName -> IO (Either SemaphoreError ClientSemaphore)
get_time_seed :: IO Int


-- | This library provides a cross-platform implementation of semaphores.
--   
--   Its main role is to provide a cross-platform notion of semaphore that
--   can be used to implement the jobserver/jobclient model of <a>GHC
--   proposal #540</a>.
--   
--   Typical usage:
--   
--   <ul>
--   <li>The jobserver creates a <a>ServerSemaphore</a>, e.g. using
--   <a>createSemaphore</a>/<a>freshSemaphore</a>.</li>
--   <li>The jobserver retrieves the serialisable
--   <a>SemaphoreIdentifier</a> of this <a>ServerSemaphore</a> by using
--   <a>serverClientSemaphore</a>, <a>clientSemaphoreName</a> and
--   <a>semaphoreIdentifier</a>.</li>
--   <li>The jobserver passes the <a>SemaphoreIdentifier</a> to the
--   jobclient via IPC.</li>
--   <li>The jobclient uses <a>openSemaphore</a> to obtain the
--   <a>ClientSemaphore</a> corresponding to the <a>SemaphoreIdentifier</a>
--   it has been given.</li>
--   <li>The jobclient can then request resources from the semaphore using
--   <a>waitOnSemaphore</a> (and return them using
--   <a>releaseSemaphoreToken</a>), or by using the <a>withAbstractSem</a>
--   bracket pattern.</li>
--   <li>Once the jobclient is done, it uses <a>destroyClientSemaphore</a>
--   to ensure all resources are released (including any remaining
--   tokens).</li>
--   <li>Once the jobserver is done, it cleans up the resources underlying
--   the semaphore using <a>destroyServerSemaphore</a>.</li>
--   </ul>
--   
--   NB: the above usage outline deliberately omits any mention of implicit
--   semaphore tokens: such a notion does not exist in this library, as
--   they are purely an abstraction layer used by the jobserver
--   implementation. See <a>destroyClientSemaphore</a> for more details.
module System.Semaphore

-- | A client-side semaphore: the handle a jobclient uses to acquire and
--   release tokens from a semaphore created by a jobserver.
--   
--   Retrieve the underlying name with <a>clientSemaphoreName</a>.
data ClientSemaphore

-- | A server-side semaphore: a <a>ClientSemaphore</a> together with the
--   book-keeping needed to track resource usage by all clients.
--   
--   Retrieve the corresponding client semaphore with
--   <a>serverClientSemaphore</a>.
data ServerSemaphore

-- | Retrieve the client-side semaphore corresponding to a server-side
--   semaphore.
serverClientSemaphore :: ServerSemaphore -> ClientSemaphore

-- | A semaphore name: a protocol version and an unversioned name string.
data SemaphoreName
SemaphoreName :: SemaphoreProtocolVersion -> String -> SemaphoreName
[semaphoreProtocolVersion] :: SemaphoreName -> SemaphoreProtocolVersion
[unversionedSemaphoreNameString] :: SemaphoreName -> String

-- | Retrieve the underlying name of a client-side semaphore.
clientSemaphoreName :: ClientSemaphore -> SemaphoreName

-- | The identifier string of a semaphore: a serialised
--   <a>SemaphoreName</a> used for inter-process communication (e.g. as a
--   command line argument).
--   
--   The specific format of this name string depends on the <b>protocol</b>
--   version:
--   
--   <ul>
--   <li>For version 1, this is the unadorned semaphore name.</li>
--   <li>For version <tt>N &gt;= 2</tt>, the semaphore name is prefixed
--   with <tt>v&lt;N&gt;-</tt>.</li>
--   </ul>
type SemaphoreIdentifier = String

-- | The serialised identifier of a <a>SemaphoreName</a> for inter-process
--   communication.
--   
--   See <a>SemaphoreIdentifier</a> for more information.
semaphoreIdentifier :: SemaphoreName -> SemaphoreIdentifier

-- | Create a new semaphore with the given label and initial token count.
createSemaphore :: String -> Int -> IO (Either SemaphoreError ServerSemaphore)

-- | Create a fresh semaphore with a unique name and the given token count.
--   
--   The name is derived from the given prefix with a random suffix.
freshSemaphore :: String -> Int -> IO (Either SemaphoreError ServerSemaphore)

-- | A held semaphore token: evidence of one unit of resource acquired from
--   a semaphore.
--   
--   Use <a>releaseSemaphoreToken</a> or <tt>withSemaphoreToken</tt> to
--   ensure prompt release of semaphore tokens.
--   
--   Platform-dependent behaviour:
--   
--   <ul>
--   <li>On POSIX, if all references to a <a>SemaphoreToken</a> are dropped
--   without being released, a finalizer returns the token to the
--   semaphore.</li>
--   <li>On Windows, tokens held by a crashed client are permanently
--   lost.</li>
--   </ul>
data SemaphoreToken

-- | Open a pre-existing semaphore.
--   
--   Returns <tt>Left SemaphoreIncompatibleVersion</tt> if the semaphore
--   protocol version is not compatible with the current version of
--   <tt>semaphore-compat</tt>.
openSemaphore :: SemaphoreIdentifier -> IO (Either SemaphoreError ClientSemaphore)

-- | Parse a <a>SemaphoreIdentifier</a> into a <a>SemaphoreName</a>.
--   
--   Returns <tt>Nothing</tt> for unversioned strings (which should be
--   treated as v1 by the caller's compatibility logic).
parseSemaphoreIdentifier :: SemaphoreIdentifier -> Maybe SemaphoreName

-- | The semaphore protocol version currently being used.
--   
--   The version tracks the IPC mechanism, not the library version:
--   
--   <ul>
--   <li><b>POSIX:</b> 2 (domain sockets, replacing v1 system
--   semaphores).</li>
--   <li><b>Windows:</b> 1 (Win32 named semaphores, unchanged from
--   v1).</li>
--   <li><b>Unsupported platforms:</b> 0 (no compatible IPC backend).</li>
--   </ul>
newtype SemaphoreProtocolVersion
SemaphoreProtocolVersion :: Int -> SemaphoreProtocolVersion
[getSemaphoreProtocolVersion] :: SemaphoreProtocolVersion -> Int

-- | The protocol version used on this host platform with this version of
--   <tt>semaphore-compat</tt>.
--   
--   See <a>SemaphoreProtocolVersion</a>.
semaphoreVersion :: SemaphoreProtocolVersion

-- | Check whether two semaphore protocol versions are compatible.
versionsAreCompatible :: SemaphoreProtocolVersion -> SemaphoreProtocolVersion -> Bool

-- | Errors that can occur when creating or opening a semaphore.
data SemaphoreError

-- | Can't create a semaphore: a semaphore with this name already exists.
SemaphoreAlreadyExists :: SemaphoreIdentifier -> SemaphoreError
[semaphoreErrorIdentifier] :: SemaphoreError -> SemaphoreIdentifier

-- | Can't open a semaphore: no semaphore with this name exists.
SemaphoreDoesNotExist :: SemaphoreIdentifier -> SemaphoreError
[semaphoreErrorIdentifier] :: SemaphoreError -> SemaphoreIdentifier

-- | Protocol version incompatibility: the semaphore identifier uses a
--   different protocol version than the library is currently using.
SemaphoreIncompatibleVersion :: SemaphoreProtocolVersion -> SemaphoreProtocolVersion -> SemaphoreError
[semaphoreErrorActualVersion] :: SemaphoreError -> SemaphoreProtocolVersion
[semaphoreErrorExpectedVersion] :: SemaphoreError -> SemaphoreProtocolVersion

-- | An <a>IOException</a> was raised when creating or opening the
--   semaphore.
SemaphoreOtherError :: IOException -> SemaphoreError
[semaphoreOtherError] :: SemaphoreError -> IOException

-- | Acquire a token from the semaphore, blocking until one is available.
--   
--   The returned <a>SemaphoreToken</a> must be released with
--   <a>releaseSemaphoreToken</a>. For prompt and predictable release of
--   resources, callers should use <a>withSemaphoreToken</a> or
--   <a>releaseSemaphoreToken</a>.
--   
--   This operation is interruptible: it can be cancelled by
--   <a>throwTo</a>, <a>killThread</a>, etc. If interrupted, any
--   transiently acquired token is automatically returned.
waitOnSemaphore :: HasCallStack => ClientSemaphore -> IO SemaphoreToken

-- | Try to acquire a token from the semaphore without blocking.
--   
--   Returns <tt>Just token</tt> if a token was available, <tt>Nothing</tt>
--   otherwise.
--   
--   This is <b>not</b> an interruptible operation, but that should not be
--   a problem: this function is not expected to block for long, as the
--   server is supposed to respond immediately.
tryWaitOnSemaphore :: HasCallStack => ClientSemaphore -> IO (Maybe SemaphoreToken)

-- | Acquire a token, run an action, then release the token. Exception
--   safe.
withSemaphoreToken :: ClientSemaphore -> (SemaphoreToken -> IO a) -> IO a

-- | Query the current semaphore value (how many tokens it has available).
--   
--   This is mainly for debugging use, as it is easy to introduce race
--   conditions when nontrivial program logic depends on the value returned
--   by this function.
getSemaphoreValue :: ServerSemaphore -> IO Int

-- | Release a semaphore token, returning it to the pool.
--   
--   Idempotent: a second call on the same token is a safe no-op.
releaseSemaphoreToken :: HasCallStack => SemaphoreToken -> IO ()

-- | Destroy a client-side semaphore.
--   
--   This is an idempotent operation: double calls to
--   <a>destroyClientSemaphore</a> do not cause any problems.
destroyClientSemaphore :: ClientSemaphore -> IO ()

-- | Destroy a server-side semaphore.
--   
--   Idempotent. Not interruptible.
destroyServerSemaphore :: ServerSemaphore -> IO ()

-- | Abstraction over the operations of a semaphore.
data AbstractSem
AbstractSem :: IO () -> IO () -> AbstractSem
[acquireSem] :: AbstractSem -> IO ()
[releaseSem] :: AbstractSem -> IO ()

-- | Acquire/release bracket pattern: acquire a token, perform an action,
--   and release the token.
--   
--   Guarantees that the token is released in case that the inner action
--   throws an exception.
withAbstractSem :: AbstractSem -> IO b -> IO b
