Package IO/THREADS-EXCEPTIONS

Types

SynchronousThreadException TYPE · src

Exceptions that a thread raises whenever it encounters a threading related problem. Unlike ThreadingException, these are actual exceptions.

Instances

ThreadingException TYPE · src

  • (InterruptCurrentThread String)

Thread exception sent asynchronously between threads. This type isn't really an exception, it's more of a message.

Instances

UnmaskFinallyMode TYPE · src

  • Stopped
  • Running

When a thread unmasks and calls a cleanup operation, the thread is either: * Still running, and will cleanup and continue * Received a stop while it was masked, and will cleanup and then terminate itself.

Instances

Values

(DYNAMIC-IS-THREADING-EXCEPTION? DYN) FUNCTION · src

(DynamicBoolean)

Returns true if the dynamic val is a threading exception or an IoError containing a ThreadingException.

(IS-THREADING-EXCEPTION IO-ERR) FUNCTION · src

(IoErrorBoolean)

Return True if IO-ERR contains a threading exception.


Package IO/EXCEPTIONS

Classes

Exceptions CLASS · src

Monad :A ⇒ Exceptions :A

A Monad that can raise and handle exceptions. IMPORTANT: Any Exceptions must catch and wrap all unhandled errors inside a wrap-io call.

Methods:
  • RAISE :: (RuntimeRepr :A) (Signalable :A) ⇒ (:A → (:B :C))
    Raise an exception.
  • RAISE-DYNAMIC :: (Dynamic → (:A :B))
    Raise an exception wrapped in a Dynamic. Mainly useful to hand-off eexceptions between IO instances.
  • RERAISE :: ((:A :B) → (Unit → (:A :C)) → (:A :B))
    Run an operation, run a catch operation if the first operation raised, then re-raise the exception. If the catch operation raises, that exception will be emitted instead of the original exception.
  • HANDLE :: RuntimeRepr :A ⇒ ((:B :C) → (:A → (:B :C)) → (:B :C))
    Run an operation, immediately handling if it raised an exception that matches :e.
  • HANDLE-ALL :: ((:A :B) → (Unit → (:A :B)) → (:A :B))
    Run an operation, immediately handling any exceptions raised.
  • TRY-DYNAMIC :: ((:A :B) → (:A (Result Dynamic :B)))
    Bring any unhandled exceptions into a Result wrapped in Dynamic.
Instances

Values

(RAISE-RESULT-DYNAMIC OP) FUNCTION · src

∀ :A :B. Exceptions :A ⇒ ((:A (Result Dynamic :B)) → (:A :B))

(RAISE-RESULT IO-RES) FUNCTION · src

∀ :A :B :C. (Exceptions :A) (RuntimeRepr :B) (Signalable :B) ⇒ ((:A (Result :B :C)) → (:A :C))

Raise any (Err :e) into :m. Useful if (Err :e) represents any unhandleable, fatal exception to the program.

(WRAP-ERROR_ THUNK) FUNCTION · src

∀ :A :B. Exceptions :B ⇒ ((Unit → :A) → (:B :A))

Run thunk, catching any unhandled Lisp/Coalton errors and raising them as exceptions.

(TRY-ALL OP) FUNCTION · src

∀ :A :B. Exceptions :A ⇒ ((:A :B) → (:A (Optional :B)))

Bring the result of OP up into an Optional. Returns None if OP raised any exceptions.

(TRY OP) FUNCTION · src

∀ :A :B :C. (Exceptions :A) (RuntimeRepr :C) ⇒ ((:A :B) → (:A (Result :C :B)))

Bring any unhandled exceptions of type :e up into a Result. Continues to carry any unhandeld exceptions not of type :e.


Macros

DO-HANDLE-ALL (OP &BODY BODY) MACRO

Convenience macro for handle-all. Example: (do-handle-all add-three-ints (modify (Cons 2)) (pure 10)) ===> (handle-all add-three-ints (const (do (modify (cons 2)) (pure 10))))

DO-HANDLE (OP (ERR-SYM) &BODY BODY) MACRO

Convenience macro for handle.

WRAP-ERROR (&BODY BODY) MACRO

Run BODY, catching any unhandled Lisp/Coalton errors and raising them as exceptions.

DO-RERAISE (OP &BODY BODY) MACRO

Convenience macro for reraise.


Package IO/MONAD-IO

Classes

UnliftIo CLASS · src

(MonadIo :A) (LiftIo :B :A) ⇒ UnliftIo :A :BMethods:
  • WITH-RUN-IN-IO :: ((((:A :B) → (:C :B)) → (:C :D)) → (:A :D))
Instances

MonadIo CLASS · src

Monad :A ⇒ MonadIo :AMethods:
  • WRAP-IO_ :: ((Unit → :A) → (:B :A))
    Wrap a (potentially) side-effectful function in the monad.
Instances

LiftIo CLASS · src

(Monad :A) (BaseIo :B) ⇒ LiftIo :B :AMethods:
  • LIFT-IO :: BaseIo :A ⇒ ((:A :B) → (:C :B))
Instances

BaseIo CLASS · src

MonadIo :A ⇒ BaseIo :A

A 'base' IO implementation, which can be run to execute some (potentially side-effectful) operation.

Methods:
  • RUN! :: ((:A :B) → :B)
    Run a (potentially) side-effectful operation. Throws any unhandled exceptions.
  • RUN-HANDLED! :: ((:A :B) → (Result Dynamic :B))
    Run a (potentially) side-effectful operation. Returns any unhandled exceptions as an (Err e).
Instances

Values

(MAP-INTO-IO ITR A->RB) FUNCTION · src

∀ :A :B :C :D :E :F. (UnliftIo :D :A) (LiftTo :D :F) (IntoIterator :B :C) ⇒ (:B → (:C → (:D :E)) → (:F (List :E)))

Efficiently perform a monadic operation for each element of an iterator and return the results. If you're having inference issues, try map-into-io_

(FOREACH-IO COLL A->MB) FUNCTION · src

∀ :A :B :C :D :E :F. (UnliftIo :D :A) (LiftTo :D :F) (IntoIterator :B :C) ⇒ (:B → ((Cell :C) → (:D :E)) → (:F Unit))

Efficiently perform a monadic operation for each element of an iterator. The next element of the iterator is passed into the operation via a cell. If your effect can be run in simple-io/IO, the version in that package will be faster!

(TIMES-IO N IO-OP) FUNCTION · src

∀ :A :B :C :D. (UnliftIo :B :A) (LiftTo :B :D) ⇒ (UFix → (:B :C) → (:D Unit))

Efficiently perform an IO operation N times. If the effect can be run in simple-io/IO, the version in that package will be faster!


Macros

DO-TIMES-IO (N &BODY BODY) MACRO

Efficiently perform an IO operation N times. If the effect can be run in simple-io/IO, the version in that package will be faster!

DERIVE-LIFT-IO (MONAD-PARAM MONADT-FORM) MACRO

Automatically derive an instance of LiftIo for a monad transformer. Example: (derive-lift-io :m (e:EnvT :e :m))

DO-FOREACH-IO ((VAR-SYM INTO-ITR) &BODY BODY) MACRO

Efficiently perform a monadic operation for each element of an iterator. VAR-SYM is bound to the value of the element in the iterator. If your effect can be run in simple-io/IO, the version in that package will be faster!

DERIVE-MONAD-IO (MONAD-PARAM MONADT-FORM) MACRO

Automatically derive an instance of MonadIo for a monad transformer. Example: (derive-monad-io :m (st:StateT :s :m))

RUN-AS! (M-TYPE M-OP) MACRO

Run M-OP using the concrete RunIo M-TYPE. Useful for situations where you want to create a generic MonadIo operation and immediately run it, so the compiler can't infer the type of the actual monad you want to use. Example: (run-as! (IO Unit) (pure Unit)) NOTE: Unfortunately, there seems to be a type inference bug that requires putting in the full type of M-OP, not just (IO :a).

WRAP-IO (&BODY BODY) MACRO

Wrap the execution of BODY in the IO monad. Supports any MonadIo instance. Example: (wrap-io (lisp :a (str) (cl:print str))

DO-MAP-INTO-IO ((VAR LST) &BODY BODY) MACRO


Package IO/SIMPLE-IO


Values

(RAISE-DYNAMIC-IO DYN) FUNCTION · src

∀ :A. (Dynamic → (IO :A))

(WITH-RUN-IN-IO_) FUNCTION · src

∀ :A :B :C. UnliftIo :A IO ⇒ ((((:A :B) → (IO :B)) → (IO :C)) → (:A :C))

`with-run-in-io`, but pegged to the simple-io implementation. Useful when you need to unlift, run, then immediately re-run a function. See, e.g., io-file:with-open-file%.

(TRY-DYNAMIC-IO IO-OP) FUNCTION · src

∀ :A. ((IO :A) → (IO (Result Dynamic :A)))

(HANDLE-ALL-IO IO-OP HANDLE-OP) FUNCTION · src

∀ :A. ((IO :A) → (Unit → (IO :A)) → (IO :A))

Run IO-OP, and run HANDLE-OP to handle exceptions of any type thrown by IO-OP.

(MAP-INTO-IO_ ITR A->MB) FUNCTION · src

∀ :A :B :C :D. (LiftIo IO :D) (IntoIterator :A :B) ⇒ (:A → (:B → (IO :C)) → (:D (List :C)))

Efficiently perform a monadic operation for each element of an iterator and return the results. More efficient than map-into-io, if you can run your effect in a BaseIo.

(FOREACH-IO_ COLL A->MB) FUNCTION · src

∀ :A :B :C :D. (LiftIo IO :D) (IntoIterator :A :B) ⇒ (:A → ((Cell :B) → (IO :C)) → (:D Unit))

Efficiently perform a monadic operation for each element of an iterator. More efficient than foreach-io, if your effect can run in IO. The next element of the iterator is passed into the operation via a cell.

(RERAISE-IO OP CATCH-OP) FUNCTION · src

∀ :A :B. ((IO :A) → (Unit → (IO :B)) → (IO :A))

(TIMES-IO_ N IO-OP) FUNCTION · src

∀ :A :B. LiftIo IO :B ⇒ (UFix → (IO :A) → (:B Unit))

Efficiently perform an IO operation N times.

(RAISE-IO_) FUNCTION · src

∀ :A. (RuntimeRepr :A) (Signalable :A) ⇒ (:A → (IO Unit))

(HANDLE-IO IO-OP HANDLE-OP) FUNCTION · src

∀ :A :B. RuntimeRepr :B ⇒ ((IO :A) → (:B → (IO :A)) → (IO :A))

(RAISE-IO E) FUNCTION · src

∀ :A :B. (RuntimeRepr :A) (Signalable :A) ⇒ (:A → (IO :B))

(RUN-IO! IO-OP) FUNCTION · src

∀ :A. ((IO :A) → :A)

Top-level run-io! that raises any unhandled exceptions. Also sets the current thread as the global thread for structured concurrency, and exits any child threads on exit.


Macros

DO-MAP-INTO-IO_ ((VAR LST) &BODY BODY) MACRO

DO-TIMES-IO_ (N &BODY BODY) MACRO

Efficiently perform an IO operation N times.

DO-FOREACH-IO_ ((VAR-SYM INTO-ITR) &BODY BODY) MACRO

Efficiently perform a monadic operation for each element of an iterator. More efficient than foreach-io, if your effect can run in IO. VAR-SYM is bound to the value of the element in the iterator.


Package IO/RESOURCE

Types

ExitCase TYPE · src

  • Completed
  • (Errored :A)

Signals the exit condition for an effectful computation using some resource.

Instances

Values

(BRACKET-IO-MASKED_ ACQUIRE-OP RELEASE-OP COMPUTATION-OP) FUNCTION · src

∀ :A :B :C :D :E :F. (Exceptions :C) (Threads :A :B :C) ⇒ ((:C :D) → (:D → (:C :E)) → (:D → (:C :F)) → (:C :F))

Acquire a resource, run a computation with it, and release it. Guarantees that RELEASE-OP will run if ACQUIRE-OP completes. If COMPUTATION-OP raises an exception, it will be re-raised after the resource cleans up. If ACQUIRE-OP or RELEASE-OP raise an exception, then release is not guaranteed. Masks the thread during the entire operation, including the computation.

(BRACKET-IO-MASKED ACQUIRE-OP RELEASE-OP COMPUTATION-OP) FUNCTION · src

∀ :A :B :C :D :E :F :G. (Exceptions :C) (Threads :A :B :C) (RuntimeRepr :E) (Signalable :E) ⇒ ((:C :D) → (:D → (ExitCase :E) → (:C :F)) → (:D → (:C :G)) → (:C :G))

WARNING: BRACKET-IO-MASKED will *only* cleanup if the raised exception matches :e, or if the computation succeedes. To guarantee cleanup after any exception, use BRACKET-IO-MASKED_ Acquire a resource, run a computation with it, and release it. Guarantees that RELEASE-OP will run if ACQUIRE-OP completes. If COMPUTATION-OP raises an exception, it will be re-raised after the resource cleans up. If ACQUIRE-OP or RELEASE-OP raise an exception, then release is not guaranteed. Masks the thread during the entire operation, including the computation.

(BRACKET-IO_ ACQUIRE-OP RELEASE-OP COMPUTATION-OP) FUNCTION · src

∀ :A :B :C :D :E :F. (Exceptions :C) (Threads :A :B :C) ⇒ ((:C :D) → (:D → (:C :E)) → (:D → (:C :F)) → (:C :F))

Acquire a resource, run a computation with it, and release it. Guarantees that RELEASE-OP will run if ACQUIRE-OP completes. If COMPUTATION-OP raises an exception, it will be re-raised after the resource cleans up. If ACQUIRE-OP or RELEASE-OP raise an exception, then release is not guaranteed. Masks the thread during resource acquisition and release. The computation is not masked, but if another thread stops this one during the computation then the resource will release before the thread is stopped.

(BRACKET-IO ACQUIRE-OP RELEASE-OP COMPUTATION-OP) FUNCTION · src

∀ :A :B :C :D :E :F :G. (Exceptions :C) (Threads :A :B :C) (RuntimeRepr :E) (Signalable :E) ⇒ ((:C :D) → (:D → (ExitCase :E) → (:C :F)) → (:D → (:C :G)) → (:C :G))

WARNING: BRACKET-IO will *only* cleanup if the raised exception matches :e, or if the computation succeedes. To guarantee cleanup after any exception, use BRACKET-IO_ Acquire a resource, run a computation with it, and release it. Guarantees that RELEASE-OP will run if ACQUIRE-OP completes. If COMPUTATION-OP raises an exception, it will be re-raised after the resource cleans up. If ACQUIRE-OP or RELEASE-OP raise an exception, then release is not guaranteed. Concurrent: - Masks the thread during resource acquisition and release. - The computation is not masked, and if another thread stops this one during the computation then the resource the resource will not be released.

(WITH-MASK OP) FUNCTION · src

∀ :A :B :C :D. (Threads :A :B :C) (Exceptions :C) ⇒ ((:C :D) → (:C :D))

Mask the current thread while running OP, automatically unmasking afterward.


Macros

DO-WITH-MASK (&BODY BODY) MACRO

Evaluate BODY with the current thread masked, automatically unmasking afterward.


Package IO/MUT

Types

Var TYPE · src

Instances

Classes

MutableVar CLASS · src

Monad :A ⇒ MutableVar :AMethods:
  • NEW-VAR :: (:A → (:B (Var :A)))
    Create a new variable with an initial value.
  • READ :: ((Var :A) → (:B :A))
    Read the current value stored in a variable.
  • WRITE :: ((Var :A) → :A → (:B :A))
    Set the value in a variable and return the old value.
  • MODIFY :: ((Var :A) → (:A → :A) → (:B :A))
    Modify the value in a variable by applying F, and return the old value.
Instances

Macros

IMPLEMENT-MUTABLE-VAR (MONAD) MACRO

DERIVE-MUTABLE-VAR (MONAD-PARAM MONADT-FORM) MACRO

Automatically derive an instance of MutableVar for a monad transformer. Example: (derive-mutable-var :m (st:StateT :s :m))


Package IO/TERM

Classes

Terminal CLASS · src

MonadIo :A ⇒ Terminal :AMethods:
  • WRITE :: Into :A String ⇒ (:A → (:B Unit))
    Write a string to standard output.
  • WRITE-LINE :: Into :A String ⇒ (:A → (:B Unit))
    Write a string to standard output followed by a newline.
  • READ-LINE :: (:A String)
    Read a line from standard input.
Instances

Macros

DERIVE-TERMINAL (MONAD-PARAM MONADT-FORM) MACRO

Automatically derive an instance of Terminal for a monad transformer. Example: (derive-terminal :m (st:StateT :s :m))

IMPLEMENT-TERMINAL (MONAD) MACRO


Package IO/RANDOM

Types

RandomState TYPE · src

Instances

Classes

RandomLimit CLASS · src

Num :A ⇒ RandomLimit :A

A number that can be used to bound a random number value.

Instances

Random CLASS · src

Monad :A ⇒ Random :AMethods:
  • MAKE-RANDOM-STATE :: (:A RandomState)
    Create a fresh random state.
  • COPY-RANDOM-STATE :: (RandomState → (:A RandomState))
    Create a copy of another random state, starting at the same seed.
  • GET-CURRENT-RANDOM-STATE :: (:A RandomState)
    Get the current thread's random state.
  • SET-CURRENT-RANDOM-STATE :: (RandomState → (:A Unit))
    Set the current thread's random state.
  • RANDOM :: RandomLimit :A ⇒ (RandomState → :A → (:B :A))
    Generate a random value less than LIMIT using the given random state.
  • RANDOM_ :: RandomLimit :A ⇒ (:A → (:B :A))
    Generate a random value less than LIMIT using the current random state.
Instances

Macros

IMPLEMENT-RANDOM (MONAD) MACRO

DERIVE-RANDOM (MONAD-PARAM MONADT-FORM) MACRO

Automatically derive an instance of Random for a monad transformer. Example: (derive-random :m (st:StateT :s :m))


Package IO/THREAD

Types

UnmaskFinallyMode TYPE · src

When a thread unmasks and calls a cleanup operation, the thread is either: * Still running, and will cleanup and continue * Received a stop while it was masked, and will cleanup and then terminate itself.

Instances

UnhandledExceptionStrategy TYPE · src

Controls what happens when a forked thread raises an exception that is not a ThreadingException. - ThrowException: Immediately throws the Dynamic value in the child thread. - LogAndSwallow: Logs the exception to *ERROR-OUTPUT* and ignore it until/if joined. - Swallow: Ignore the error until/if joined.

Instances

TimeoutStrategy TYPE · src

Controls whether blocking IO operations use a timeout in milliseconds.

Instances

Generation TYPE · src

Instances

ForkScope TYPE · src

Controls whether a forked thread is attached to a scope, and if so which one. - Structured: Attach to the current thread's scope. - StructuredIn: Attach to the provided thread handle's scope. - Detached: Attach to the global scope; the thread will end with the toplevel run!.

Instances

Structs

IoThread STRUCT · src

Instances

ForkStrategy :A STRUCT · src

Strategy object controlling fork behavior (exception semantics + structured concurrency).

Instances

Classes

Concurrent CLASS · src

Concurrent :A :B

A Concurrent has thread-like semantics. It can be stopped, masked, unmasked, and await-ed. Concurrents don't have a uniform fork function, becasue they require different initialization input.

Methods:
  • STOP :: (Exceptions :A) (Threads :B :C :A) ⇒ (:D → (:A Unit))
    Stop a Concurrent. If the Concurrent has already stopped, does nothing. If the Concurrent is masked, this will pend a stop on the Concurrent. When/if the Concurrent becomes completely unmaksed, it will stop iself. Regardless of whether the target Concurrent is masked, STOP does not block or wait for the target to complete.
  • AWAIT :: (Exceptions :A) (Threads :B :C :A) ⇒ (:D → (:A :E))
    Block the current thread until the target Concurrent is completed, and retrieve its value. Re-raises if the target Concurrent raised an unhandled exception
  • MASK :: (Exceptions :A) (Threads :B :C :A) ⇒ (:D → (:A Unit))
    Mask the Concurrent so it can't be stopped.
  • UNMASK :: (Exceptions :A) (Threads :B :C :A) ⇒ (:D → (:A Unit))
    Unmask the Concurrent so it can be stopped. Unmask respects nested masks - if the Concurrent has been masked N times, it can only be stopped after being unmasked N times. When the Concurrent unmasks, if there are any pending stops, it will immediately stop itself.
  • UNMASK-FINALLY :: (UnliftIo :A :B) (LiftTo :A :C) (Threads :D :E :A) (Exceptions :C) (Threads :D :E :C) ⇒ (:F → (UnmaskFinallyMode → (:A :G)) → (:C Unit))
    Unmask the thread, run the provided action, and then honor any pending stop for that thread after the action finishes. Warning: There is a very small chance that the UnmaskFinallyMode passed to the callback could be inconsistent with whether the Concurrent is ultimately stopped. Regardless of the input, the callback should leave any resources in a valid state. An example of a valid callback: closing a log file if the thread is stopped, or closing the log file with a final message if the thread is continuing.
Instances

Threads CLASS · src

(MonadIo :A) (Runtime :B :C) ⇒ Threads :B :C :A

A MonadIo which can spawn :t's. Other :t's error separately. A spawned :t erroring will not cause the parent :t to fail. :t can be any 'thread-like' object, depending on the underlying implementation - system threads, software-managed green threads, etc.

Instances

Runtime CLASS · src

Runtime :A :B

This class doesn't represent data, but the type tells a Concurrent and a Threads how to hook into the native threading implementations that a runtime provides. A runtime has a 'base' concurrent, which is the underlying thread/fiber/etc. that the runtime produces to run concurrently. All other Concurrents are built by composing on the base concurrent somehow. Runtime is a low-level type that operates inside the normal MonadIo layer. It should not be used by normal application code. Its two main purposes are: (1) to make Threads generic over the type of thread it forks, and (2) to build low-level, efficient concurrency tools that are generic over the underlying thread type.

Methods:
  • CURRENT-THREAD! :: ((Proxy :A) → :B)
    Get a handle for the current thread.
  • SLEEP! :: ((Proxy :A) → UFixUnit)
    Sleep the current thread for MSECS milliseconds.
  • FORK! :: ((Proxy :A) → (ForkStrategy :B) → (Unit → (Result Dynamic :C)) → :B)
    Spawn a new thread, which starts running immediately. Returns the handle to the thread. The ForkStrategy controls both: - how unhandled exceptions behave, and - whether the fork is structured (and which thread's scope owns it).
  • JOIN! :: ((Proxy :A) → :B → (Result Dynamic Unit))
    Block the current thread until the target thread is completed. Does not a retrieve value. Raises an exception if the target thread raised an unhandled exception, wrapping the target thread's raised exception. JOIN! is the lowest level operation to block on another thread's termination, and most code should use AWAIT instead.
  • STOP! :: ((Proxy :A) → :B → Unit)
    Stop a :t. If the thread has already stopped, does nothing. If the :t is masked, this will pend a stop on the :t. When/if the :t becomes completely unmaksed, it will stop iself. Regardless of whether the target :t is masked, STOP does not block or wait for the target thread to complete.
  • MASK! :: ((Proxy :A) → :B → Unit)
    Mask the thread so it can't be stopped.
  • UNMASK! :: ((Proxy :A) → :B → Unit)
    Unmask the thread so it can be stopped. Unmask respects nested masks - if the thread has been masked N times, it can only be stopped after being unmasked N times. When the thread unmasks, if there are any pending stops, it will immediately be stopped.
  • UNMASK-FINALLY! :: ((Proxy :A) → :B → (UnmaskFinallyMode → :C) → Unit)
    Unmask the thread, run the provided action, and then honor any pending stop for that thread after the action finishes. Warning: There is a very small chance that the UnmaskFinallyMode passed to the callback could be inconsistent with whether the Concurrent is ultimately stopped. Regardless of the input, the callback should leave any resources in a valid state. An example of a valid callback: closing a log file if the thread is stopped, or closing the log file with a final message if the thread is continuing.
  • PARK-CURRENT-THREAD-IF! :: ((Proxy :A) → (GenerationUnit) → (UnitBoolean) → Unit)
    Parks the current thread if SHOULD-PARK? returns True. Will park the thread until woken by an unpark from another thread. Upon an unpark, the thread will resume even if SHOULD-PARK? is False! SHOULD-PARK? is only checked to determine if the thread should park, *not* if it should resume. Concurrent: - WARNING: SHOULD-PARK? must not block, or the thread could be left blocked in a masked state. - Can briefly block while trying to park the thread, if contended.
  • PARK-CURRENT-THREAD-IF-WITH! :: ((Proxy :A) → (GenerationUnit) → (UnitBoolean) → TimeoutStrategyUnit)
    Parks the current thread if SHOULD-PARK? returns True. Will park the thread until woken by an unpark from another thread. Upon an unpark, the thread will resume even if SHOULD-PARK? is False! SHOULD-PARK? is only checked to determine if the thread should park, *not* if it should resume. Concurrent: - WARNING: SHOULD-PARK? must not block, or the thread could be left blocked in a masked state. - Can briefly block while trying to park the thread, if contended.
  • UNPARK-THREAD! :: ((Proxy :A) → Generation → :B → Unit)
    Unparks the thread if it is still waiting on the generation. Attempting to unpark the thread with a stale generation has no effect. A generation will be stale if the thread has unparked and re-parked since the initial park. Concurrent: - Can briefly block while trying to unpark the thread, if contended.
Instances

Values

(WRITE-LINE-SYNC MSG) FUNCTION · src

∀ :A :B. (Into :A String) (Terminal :B) ⇒ (:A → (:B Unit))

Perform a synchrozied write-line to the terminal. Not performant - mainly useful for debugging.

(PARK-CURRENT-THREAD-IF_) FUNCTION · src

∀ :A. MonadIo :A ⇒ ((Generation → (IO Unit)) → (IO Boolean) → (:A Unit))

Parks the current thread if SHOULD-PARK? returns True. Will park the thread until woken by an unpark from another thread. Upon an unpark, the thread will resume even if SHOULD-PARK? is False! SHOULD-PARK? is only checked to determine if the thread should park, *not* if it should resume. Concurrent: - WARNING: SHOULD-PARK? must not block, or the thread could be left blocked in a masked state. - Can briefly block while trying to park the thread, if contended.

(UNMASK-THREAD-FINALLY_) FUNCTION · src

∀ :A :B. (LiftTo IO :B) (Exceptions :B) (Threads IoRuntime IoThread :B) ⇒ (IoThread → (UnmaskFinallyMode → (IO :A)) → (:B Unit))

(FORK-THREAD-WITH_) FUNCTION · src

∀ :A :B. (Threads IoRuntime IoThread :B) (LiftTo IO :B) ⇒ ((ForkStrategy IoThread) → (IO :A) → (:B IoThread))

(UNMASK-FINALLY_) FUNCTION · src

∀ :A :B :C :D. (LiftTo IO :D) (Exceptions :D) (Concurrent :B :A) (Threads IoRuntime IoThread :D) ⇒ (:B → (UnmaskFinallyMode → (IO :C)) → (:D Unit))

(FORK-THREAD_) FUNCTION · src

∀ :A :B. (Threads IoRuntime IoThread :B) (LiftTo IO :B) ⇒ ((IO :A) → (:B IoThread))

(UNMASK-CURRENT-THREAD-FINALLY OP-FINALLY) FUNCTION · src

∀ :A :B :C :D :E. (UnliftIo :D :A) (LiftTo :D :E) (Threads :B :C :D) ⇒ ((UnmaskFinallyMode → (:D Unit)) → (:E Unit))

Unmask the current thread, run the provided action, and then honor any pending stop for that thread after the action finishes. Warning: There is a very small chance that the UnmaskFinallyMode passed to the callback could be inconsistent with whether the Concurrent is ultimately stopped. Regardless of the input, the callback should leave any resources in a valid state. An example of a valid callback: closing a log file if the thread is stopped, or closing the log file with a final message if the thread is continuing.

(PARK-CURRENT-THREAD-IF-WITH WITH-GEN SHOULD-PARK? STRATEGY) FUNCTION · src

∀ :A :B :C :D. (BaseIo :C) (Threads :A :B :C) (MonadIo :D) ⇒ ((Generation → (:C Unit)) → (:C Boolean) → TimeoutStrategy → (:D Unit))

Parks the current thread if SHOULD-PARK? returns True. Will park the thread until woken by an unpark from another thread. Upon an unpark, the thread will resume even if SHOULD-PARK? is False! SHOULD-PARK? is only checked to determine if the thread should park, *not* if it should resume. Concurrent: - WARNING: SHOULD-PARK? must not block, or the thread could be left blocked in a masked state. - Can briefly block while trying to park the thread, if contended.

(PARK-CURRENT-THREAD-IF WITH-GEN SHOULD-PARK?) FUNCTION · src

∀ :A :B :C :D. (BaseIo :C) (Threads :A :B :C) (MonadIo :D) ⇒ ((Generation → (:C Unit)) → (:C Boolean) → (:D Unit))

Parks the current thread if SHOULD-PARK? returns True. Will park the thread until woken by an unpark from another thread. Upon an unpark, the thread will resume even if SHOULD-PARK? is False! SHOULD-PARK? is only checked to determine if the thread should park, *not* if it should resume. Concurrent: - WARNING: SHOULD-PARK? must not block, or the thread could be left blocked in a masked state. - Can briefly block while trying to park the thread, if contended.

(UNMASK-THREAD-FINALLY THREAD OP-FINALLY) FUNCTION · src

∀ :A :B :C :D :E :F. (UnliftIo :D :A) (LiftTo :D :F) (Threads :B :C :D) ⇒ (:C → (UnmaskFinallyMode → (:D :E)) → (:F Unit))

Unmask the thread, run the provided action, and then honor any pending stop for that thread after the action finishes. Warning: There is a very small chance that the UnmaskFinallyMode passed to the callback could be inconsistent with whether the Concurrent is ultimately stopped. Regardless of the input, the callback should leave any resources in a valid state. An example of a valid callback: closing a log file if the thread is stopped, or closing the log file with a final message if the thread is continuing.

UNMASK-CURRENT-THREAD VALUE · src

∀ :A :B :C. Threads :A :B :C ⇒ (:C Unit)

Unmask the current thread so it can be stopped. Unmask respects nested masks - if the thread has been masked N times, it can only be stopped after being unmasked N times.

MASK-CURRENT-THREAD VALUE · src

∀ :A :B :C. Threads :A :B :C ⇒ (:C Unit)

Mask the current thread so it can't be stopped.

(FORK-THREAD-WITH STRAT OP) FUNCTION · src

∀ :A :B :C :D :E :F. (UnliftIo :D :A) (LiftTo :D :F) (Threads :B :C :D) ⇒ ((ForkStrategy :C) → (:D :E) → (:F :C))

Spawn a new thread using STRAT. This version can accept any underlying BaseIo, which can be useful, but causes inference issues in some cases.

(UNMASK-CURRENT! RT-PRX) FUNCTION · src

∀ :A :B. Runtime :B :A ⇒ ((Proxy :B) → Unit)

Unmask the current thread.

CURRENT-THREAD VALUE · src

∀ :A :B :C. Threads :A :C :B ⇒ (:B :C)

Get the current thread.

(UNPARK-THREAD GEN THREAD) FUNCTION · src

∀ :A :B :C. Threads :A :B :C ⇒ (Generation → :B → (:C Unit))

Unparks the thread if it is still waiting on the generation. Attempting to unpark the thread with a stale generation has no effect. A generation will be stale if the thread has unparked and re-parked since the initial park. Concurrent: - Can briefly block while trying to unpark the thread, if contended.

(UNMASK-THREAD THREAD) FUNCTION · src

∀ :A :B :C. Threads :A :B :C ⇒ (:B → (:C Unit))

Unmask the thread so it can be stopped. Unmask respects nested masks - if the thread has been masked N times, it can only be stopped after being unmasked N times.

(MASK-CURRENT! RT-PRX) FUNCTION · src

∀ :A :B. Runtime :B :A ⇒ ((Proxy :B) → Unit)

Mask the current thread.

(STOP-THREAD THREAD) FUNCTION · src

∀ :A :B :C. Threads :A :B :C ⇒ (:B → (:C Unit))

Stop a thread. If the thread has already stopped, does nothing.

(MASK-THREAD THREAD) FUNCTION · src

∀ :A :B :C. Threads :A :B :C ⇒ (:B → (:C Unit))

Mask the thread so it can't be stopped.

(JOIN-THREAD THREAD) FUNCTION · src

∀ :A :B :C. (Threads :A :B :C) (Exceptions :C) ⇒ (:B → (:C Unit))

Block the current thread until the target thread is completed. Does not a retrieve value. Raises an exception if the target thread raised an unhandled exception, wrapping the target thread's raised exception. JOIN-THREAD is the lowest level operation to block on another thread's termination.

(FORK-THREAD OP) FUNCTION · src

∀ :A :B :C :D :E :F. (UnliftIo :C :A) (LiftTo :C :E) (Threads :B :F :C) ⇒ ((:C :D) → (:E :F))

Spawn a new thread, which starts running immediately. Returns the handle to the thread. If the thread raises an unhandled exception, it will be logged to *ERROR-OUTPUT* and swallowed, until/if the thread is joined. This is the default fork behavior: structured + log-and-swallow.

(SLEEP MSEC) FUNCTION · src

∀ :A :B :C. Threads :A :B :C ⇒ (UFix → (:C Unit))

Sleep the current thread for MSECS milliseconds.


Macros

DO-FORK-THREAD (&BODY BODY) MACRO

DO-FORK-THREAD_ (&BODY BODY) MACRO

DERIVE-THREADS (MONAD-PARAM MONADT-FORM) MACRO

Automatically derive an instance of Threads for a monad transformer. Example: (derive-threads :m (st:StateT :s :m))

IMPLEMENT-THREADS (MONAD RUNTIME THREAD) MACRO

DO-FORK-THREAD-WITH_ (STRATEGY &BODY BODY) MACRO

DO-FORK-THREAD-WITH (STRATEGY &BODY BODY) MACRO


Package IO/FILE

Classes

Files CLASS · src

MonadIo :A ⇒ Files :AMethods:
Instances

Values

(WITH-TEMP-DIRECTORY K) FUNCTION · src

∀ :A :B :C :D :E :F. (UnliftIo :D :A) (LiftTo :D :F) (Exceptions :A) (Files :A) (Threads :B :C :A) ⇒ ((Pathname → (:D :E)) → (:F :E))

Performs an operation `thunk` inside a temporary directory. Can run any underlying BaseIo, which can be useful but can also cause inference issues in some cases. Try WITH-TEMP-DIRECTORY_ if you have issues.

(WITH-TEMP-FILE FILE-TYPE K) FUNCTION · src

∀ :A :B :C :D :E :F :G. (File :D) (Files :A) (Threads :B :C :A) (UnliftIo :E :A) (LiftTo :E :G) (Exceptions :A) ⇒ (String → ((FileStream :D) → (:E :F)) → (:G :F))

Performs an operation `thunk` on a temporary file. File type extensions need to include `.` Can run any underlying BaseIo, which can be useful but can also cause inference issues in some cases. Try WITH-TEMP-FILE_ if you have issues.

(WITH-OPEN-FILE OPTS K) FUNCTION · src

∀ :A :B :C :D :E :F :G. (File :D) (Files :A) (UnliftIo :E :A) (LiftTo :E :G) (Exceptions :A) (Threads :B :C :A) ⇒ (StreamOptions → ((FileStream :D) → (:E :F)) → (:G :F))

Opens a file stream, performs K on it, then closes the stream. Can run any underlying BaseIo, which can be useful but can also cause inference issues in some cases. Try WITH-OPEN-FILE_ if you have issues.

(WITH-TEMP-DIRECTORY_) FUNCTION · src

∀ :A :B. (UnliftIo :B IO) (LiftTo IO :B) ⇒ ((Pathname → (IO :A)) → (:B :A))

(WITH-TEMP-FILE_) FUNCTION · src

∀ :A :B :C. (File :A) (UnliftIo :C IO) (LiftTo IO :C) ⇒ (String → ((FileStream :A) → (IO :B)) → (:C :B))

(WITH-OPEN-FILE_) FUNCTION · src

∀ :A :B :C. (File :A) (UnliftIo :C IO) (LiftTo IO :C) ⇒ (StreamOptions → ((FileStream :A) → (IO :B)) → (:C :B))

Macros

DO-WITH-TEMP-DIRECTORY ((DIR) &BODY BODY) MACRO

`do` sugar for `with-temp-directory`.

DERIVE-FILES (MONAD-PARAM MONADT-FORM) MACRO

Derive a `Files` instance for MONADT-FORM by lifting into the base instance. Example: (derive-files :m (st:StateT :s :m))

DO-WITH-OPEN-FILE (OPTS (FS) &BODY BODY) MACRO

`do` sugar for `with-open-file`. Expands to a continuation where BODY runs in `do`. Usage: (do-with-open-file opts (fs) (line <- (read-char fs)) ...)

DO-WITH-TEMP-DIRECTORY_ ((DIR) &BODY BODY) MACRO

`do` sugar for `with-temp-directory_`.

DO-WITH-OPEN-FILE_ (OPTS (FS) &BODY BODY) MACRO

`do` sugar for `with-open-file_`. Expands to a continuation where BODY runs in `do`. Usage: (do-with-open-file_ opts (fs) (line <- (read-char fs)) ...)

DO-WITH-TEMP-FILE_ (TYPE (FS) &BODY BODY) MACRO

`do` sugar for `with-temp-file_` (TYPE is a string like "txt").

DO-WITH-TEMP-FILE (TYPE (FS) &BODY BODY) MACRO

`do` sugar for `with-temp-file` (TYPE is a string like "txt").

IMPLEMENT-FILES (MONAD) MACRO


Package IO/UNIQUE

Types

Unique TYPE · src

Instances

Classes

UniqueGen CLASS · src

Monad :A ⇒ UniqueGen :AMethods:
  • NEW-UNIQUE :: (:A Unique)
    Generate a value that will be unique within this run of the program. Threadsafe - calling from different threads will still result in unique values across all threads.
Instances

Values

(TO-INT (UNIQUE% I)) FUNCTION · src

(UniqueInteger)

Convert a unique value to an integer. It is guaranteed that: (/= (to-int a) (to-int b)) for any two different Unique instances.


Macros

IMPLEMENT-UNIQUE-GEN (MONAD) MACRO

DERIVE-UNIQUE-GEN (MONAD-PARAM MONADT-FORM) MACRO

Automatically derive an instance of UniqueGen for a monad transformer. Example: (derive-unique-gen :m (st:StateT :s :m))


Package IO/NETWORK

Types

ByteConnectionSocket TYPE · src

A socket connecting a client and server using a byte stream.

Instances

ConnectionSocket TYPE · src

A socket connecting a client and server.

Instances

ByteServerSocket TYPE · src

A server socket listening for new byte-stream connections.

Instances

ServerSocket TYPE · src

A server socket listening for new connections.

Instances

Classes

Sockets CLASS · src

MonadIo :A ⇒ Sockets :AMethods:
Instances

Values

(BYTE-SOCKET-ACCEPT-FORK-WITH SERVER-SOCKET OP) FUNCTION · src

∀ :A :B :C :D. (Sockets :B) (Threads :A :D :B) (Exceptions :B) (UnliftIo :B :B) ⇒ (ByteServerSocket → (ByteConnectionSocket → (:B :C)) → (:B :D))

Accept a byte-stream connection with a new client and run operation OP on a new thread. Guarantees that the socket will close on cleanup. Returns a handle to the forked thread.

(BYTE-SOCKET-CONNECT-WITH HOSTNAME PORT OP) FUNCTION · src

∀ :A :B :C :D. (Sockets :C) (Threads :A :B :C) (Exceptions :C) ⇒ (StringUFix → (ByteConnectionSocket → (:C :D)) → (:C :D))

Run operation OP with a byte-stream connection to an open server socket at HOSTNAME and PORT. Guarantees that the socket will close on cleanup.

(SOCKET-ACCEPT-FORK-WITH SERVER-SOCKET OP) FUNCTION · src

∀ :A :B :C :D. (Sockets :B) (Threads :A :D :B) (Exceptions :B) (UnliftIo :B :B) ⇒ (ServerSocket → (ConnectionSocket → (:B :C)) → (:B :D))

Accept a connection with a new client and run operation OP on a new thread. Guarantees that the socket will close on cleanup. Returns a handle to the forked thread.

(BYTE-SOCKET-LISTEN-WITH HOSTNAME PORT OP) FUNCTION · src

∀ :A :B :C :D. (Sockets :C) (Threads :A :B :C) (Exceptions :C) ⇒ (StringUFix → (ByteServerSocket → (:C :D)) → (:C :D))

Run operation OP with a new byte-stream server socket, listening on HOSTNAME and PORT. Guarantees that the socket will close on cleanup.

(BYTE-SOCKET-ACCEPT-WITH SERVER-SOCKET OP) FUNCTION · src

∀ :A :B :C :D. (Sockets :C) (Threads :A :B :C) (Exceptions :C) ⇒ (ByteServerSocket → (ByteConnectionSocket → (:C :D)) → (:C :D))

Accept a byte-stream connection with a new client and run operation OP. Guarantees that the socket will close on cleanup. Note: If you fork a thread inside this, the operation on this thread will probably finish and close the socket before you intend. For multithreaded uses, use byte-socket-accept-fork-with.

(SOCKET-CONNECT-WITH HOSTNAME PORT OP) FUNCTION · src

∀ :A :B :C :D. (Sockets :C) (Threads :A :B :C) (Exceptions :C) ⇒ (StringUFix → (ConnectionSocket → (:C :D)) → (:C :D))

Run operation OP with a connection to an open server socket at HOSTNAME and PORT. Guarantees that the socket will close on cleanup.

(SOCKET-LISTEN-WITH HOSTNAME PORT OP) FUNCTION · src

∀ :A :B :C :D. (Sockets :C) (Threads :A :B :C) (Exceptions :C) ⇒ (StringUFix → (ServerSocket → (:C :D)) → (:C :D))

Run operation OP with a new server socket, listening on HOSTNAME and PORT. Guarantees that the socket will close on cleanup.

(SOCKET-ACCEPT-WITH SERVER-SOCKET OP) FUNCTION · src

∀ :A :B :C :D. (Sockets :C) (Threads :A :B :C) (Exceptions :C) ⇒ (ServerSocket → (ConnectionSocket → (:C :D)) → (:C :D))

Accept a connection with a new client and run operation OP. Guarantees that the socket will close on cleanup. Note: If you fork a thread inside this, the operation on this thread will probably finish and close the socket before you intend. For multithreaded uses, use socket-accept-fork-with.


Macros

DERIVE-SOCKETS (MONAD-PARAM MONADT-FORM) MACRO

Automatically derive an instance of Sockets for a monad transformer. Example: (derive-sockets :m (st:StateT :s :m))

DO-BYTE-SOCKET-ACCEPT-FORK-WITH ((SOCKET-SYM (SERVER-SOCKET)) &BODY BODY) MACRO

Accept a byte-stream connection with a new client and run operation OP on a new thread. Guarantees that the socket will close on cleanup. Returns a handle to the forked thread.

DO-SOCKET-LISTEN-WITH ((SOCKET-SYM (HOSTNAME PORT)) &BODY BODY) MACRO

Run operation OP with a new server socket, listening on HOSTNAME and PORT. Guarantees that the socket will close on cleanup.

DO-SOCKET-ACCEPT-FORK-WITH ((SOCKET-SYM (SERVER-SOCKET)) &BODY BODY) MACRO

Accept a connection with a new client and run operation OP on a new thread. Guarantees that the socket will close on cleanup. Returns a handle to the forked thread.

DO-SOCKET-CONNECT-WITH ((SOCKET-SYM (HOSTNAME PORT)) &BODY BODY) MACRO

Run operation OP with a connection to an open server socket at HOSTNAME and PORT. Guarantees that the socket will close on cleanup.

DO-SOCKET-ACCEPT-WITH ((SOCKET-SYM (SERVER-SOCKET)) &BODY BODY) MACRO

Accept a connection with a new client and run operation OP. Guarantees that the socket will close on cleanup. Note: If you fork a thread inside this, the operation on this thread will probably finish and close the socket before you intend. For multithreaded uses, use socket-accept-fork-with.

DO-BYTE-SOCKET-ACCEPT-WITH ((SOCKET-SYM (SERVER-SOCKET)) &BODY BODY) MACRO

Accept a byte-stream connection with a new client and run operation OP. Guarantees that the socket will close on cleanup. Note: If you fork a thread inside this, the operation on this thread will probably finish and close the socket before you intend. For multithreaded uses, use byte-socket-accept-fork-with.

IMPLEMENT-SOCKETS (MONAD) MACRO

DO-BYTE-SOCKET-LISTEN-WITH ((SOCKET-SYM (HOSTNAME PORT)) &BODY BODY) MACRO

Run operation OP with a new byte-stream server socket, listening on HOSTNAME and PORT. Guarantees that the socket will close on cleanup.

DO-BYTE-SOCKET-CONNECT-WITH ((SOCKET-SYM (HOSTNAME PORT)) &BODY BODY) MACRO

Run operation OP with a byte-stream connection to an open server socket at HOSTNAME and PORT. Guarantees that the socket will close on cleanup.


Package IO/CONC/PARKING

Types

ParkingSet TYPE · src

ParkingSet is a thread-safe list of parked threads. A parking thread can atomically subscibe and park on a Parking Set, and a signalling thread can atomically unpark all parkers on a ParkingSet. In general, ParkingSet is the preferred way to park and unpark threads. The lower-level parking functions exposed by the Threads and Runtime classes should only be used if ParkingSet doesn't provide enough functionality for the algorithm. Concurrent: - ParkingSet's algorithms are lock free, but individual threads can block for a very short window if contention on the parking set is very high.

Instances

Values

(PARK-IN-SETS-IF-WITH SHOULD-PARK? STRATEGY PSETS) FUNCTION · src

∀ :A :B :C :D. (BaseIo :C) (Threads :A :B :C) (MonadIo :D) ⇒ ((:C Boolean) → TimeoutStrategy → (List ParkingSet) → (:D Unit))

Parks the current thread in PSETS if SHOULD-PARK? returns True. Will park the thread until woken by an unpark from another thread. Upon an unpark, the thread will resume even if SHOULD-PARK? is False! SHOULD-PARK? is only checked to determine if the thread should park, *not* if it should resume. Concurrent: - WARNING: SHOULD-PARK? must not block, or the thread could be left blocked in a masked state. - Can briefly block while trying to park the thread, if contended.

(PARK-IN-SET-IF-WITH SHOULD-PARK? STRATEGY PSET) FUNCTION · src

∀ :A :B :C :D. (BaseIo :C) (Threads :A :B :C) (MonadIo :D) ⇒ ((:C Boolean) → TimeoutStrategyParkingSet → (:D Unit))

Parks the current thread in PSET if SHOULD-PARK? returns True. Will park the thread until woken by an unpark from another thread. Upon an unpark, the thread will resume even if SHOULD-PARK? is False! SHOULD-PARK? is only checked to determine if the thread should park, *not* if it should resume. Concurrent: - WARNING: SHOULD-PARK? must not block, or the thread could be left blocked in a masked state. - Can briefly block while trying to park the thread, if contended.

(PARK-IN-SETS-IF SHOULD-PARK? PSETS) FUNCTION · src

∀ :A :B :C :D. (BaseIo :C) (Threads :A :B :C) (MonadIo :D) ⇒ ((:C Boolean) → (List ParkingSet) → (:D Unit))

Parks the current thread in PSETS if SHOULD-PARK? returns True. Will park the thread until woken by an unpark from another thread. Upon an unpark, the thread will resume even if SHOULD-PARK? is False! SHOULD-PARK? is only checked to determine if the thread should park, *not* if it should resume. Concurrent: - WARNING: SHOULD-PARK? must not block, or the thread could be left blocked in a masked state. - Can briefly block while trying to park the thread, if contended.

NEW-PARKING-SET VALUE · src

∀ :A. MonadIo :A ⇒ (:A ParkingSet)

Create a new ParkingSet.

(PARK-IN-SET-IF SHOULD-PARK? PSET) FUNCTION · src

∀ :A :B :C :D. (BaseIo :C) (Threads :A :B :C) (MonadIo :D) ⇒ ((:C Boolean) → ParkingSet → (:D Unit))

Parks the current thread in PSET if SHOULD-PARK? returns True. Will park the thread until woken by an unpark from another thread. Upon an unpark, the thread will resume even if SHOULD-PARK? is False! SHOULD-PARK? is only checked to determine if the thread should park, *not* if it should resume. Concurrent: - WARNING: SHOULD-PARK? must not block, or the thread could be left blocked in a masked state. - Can briefly block while trying to park the thread, if contended.

(UNPARK-SET PSET) FUNCTION · src

∀ :A. MonadIo :A ⇒ (ParkingSet → (:A Unit))

Atomically reset PSET, then attempt to unpark all threads parked on the set. Concurrent: - Can briefly block while trying to reset the set or unpark a parked thread

(PARK-IN-SETS-IF_) FUNCTION · src

∀ :A. MonadIo :A ⇒ ((IO Boolean) → (List ParkingSet) → (:A Unit))

Parks the current thread in PSETS if SHOULD-PARK? returns True. Will park the thread until woken by an unpark from another thread. Upon an unpark, the thread will resume even if SHOULD-PARK? is False! SHOULD-PARK? is only checked to determine if the thread should park, *not* if it should resume. Concurrent: - WARNING: SHOULD-PARK? must not block, or the thread could be left blocked in a masked state. - Can briefly block while trying to park the thread, if contended.

(PARK-IN-SET-IF_) FUNCTION · src

∀ :A. MonadIo :A ⇒ ((IO Boolean) → ParkingSet → (:A Unit))

Parks the current thread in PSET if SHOULD-PARK? returns True. Will park the thread until woken by an unpark from another thread. Upon an unpark, the thread will resume even if SHOULD-PARK? is False! SHOULD-PARK? is only checked to determine if the thread should park, *not* if it should resume. Concurrent: - WARNING: SHOULD-PARK? must not block, or the thread could be left blocked in a masked state. - Can briefly block while trying to park the thread, if contended.


Package IO/CONC/SCHEDULER

Classes

Scheduler CLASS · src

Scheduler :A

A Scheduler distributes work from producer threads to worker threads. Generally, the Scheduler is allowed to completely control the worker threads: it can sleep, block, spin, etc., as dictated by the Scheduler algorithm. However, it must give producer threads the choice of how to respond to the state of the Scheduler. For example, if the Scheduler is bounded and its internal queue is full, the producer thread chooses whether to block or fail based on its choice of which submit function to call. The main purpose of a Scheduler is to pass into a WorkerPool to configure its scheduling algorithm. A Scheduler could have uses in other contexts. A Scheduler may be bounded or unbounded and still satisfy the Scheduler interface. For unbounded schedulers, `submit` will never block and `try-submit` will always succeed. Threads asking for work will submit a thread-index to the scheduler. The Scheduler can choose to use this, particularly if it maintains a separate queue for each thread, or choose to ignore it, if it only uses a single queue for all threads. Thread index values should be 0-indexed, from [0, n-threads).

Methods:
  • SUBMIT :: Threads :A :B :C ⇒ (:D → (:E :D) → (:C Unit))
    Submit a new item to the Scheduler. Concurrent: - Blocks if the Scheduler is full. Only bounded Schedulers will ever be full.
  • SUBMIT-WITH :: Threads :A :B :C ⇒ (:D → TimeoutStrategy → (:E :D) → (:C Unit))
    Submit a new item to the Scheduler. Concurrent: - Blocks if the Scheduler is full, possibly timing out based on STRATEGY. Only bounded Schedulers will ever be full.
  • TRY-SUBMIT :: Threads :A :B :C ⇒ (:D → (:E :D) → (:C Boolean))
    Attempt to submit a new item to the Scheduler. Returns `True` if the item was added, or `False` if the Scheduler was full. Only bounded Schedulers can be full.
  • TAKE-ITEM :: Threads :A :B :C ⇒ (UFix → (:D :E) → (:C :E))
    Take the next item from the Scheduler for the given thread. Concurrent: - May block, sleep, spin, or do anything else to the requesting thread, except (1) leave it masked after returning, or (2) stop the thread.
Instances

Package IO/CONC/FUTURE

Structs

Future :A STRUCT · src

Container for an value that will eventually be returned by a concurrent operation. Concurrent: - Future's `(Concurrent Future :a)` instance defers to the underlying thread, so it takes on masking semantics of the underyling thread's `Concurrent` instance.

Instances

Values

(TRY-READ-FUTURE FUTURE) FUNCTION · src

∀ :A :B :C :D. (Threads :A :B :D) (Exceptions :D) ⇒ ((Future :C) → (:D (Optional :C)))

Try to read the current value from FUTURE, returning NONE if it is not available. Raises any exceptions in the awaiting thread that were raised in the future thread.

(FORK-FUTURE TASK) FUNCTION · src

∀ :A :B :C :D :E :F. (Exceptions :D) (LiftTo :D :F) (UnliftIo :D :A) (Threads :B :C :D) (Threads :B :C :F) ⇒ ((:D :E) → (:F (Future :E)))

Spawn a new future, which will run and eventually return the result from TASK. The future is guaranteed to only ever run at most once, when the produced :m is run.

(FORK-FUTURE_) FUNCTION · src

∀ :A :B. (Threads IoRuntime IoThread :B) (LiftTo IO :B) ⇒ ((IO :A) → (:B (Future :A)))

Spawn a new future, which will run and eventually return the result from TASK. The future is guaranteed to only ever run at most once, when the produced :m is run.


Macros

DO-FORK-FUTURE (&BODY BODY) MACRO

Spawn a new future, which will run and eventually return the result from TASK. The future is guaranteed to only ever run at most once, when the produced :m is run.

DO-FORK-FUTURE_ (&BODY BODY) MACRO


Package IO/CONC/ATOMIC

Types

AtVar TYPE · src

A container that can be read and modified atomically.

Instances

Values

(MODIFY-SWAP ATM F) FUNCTION · src

∀ :A :B. MonadIo :B ⇒ ((AtVar :A) → (:A → :A) → (:B :A))

Atomically modify `atm` by applying `f` and return the old value. `f` must be a pure function. If `f` throws an error, `atm` will be unchanged and the error will be handleable via `Exceptions`. Concurrent: - WARNING: `f` will be retried each time the calling thread loses the race to update `atm`, so `f` must be pure.

(NEW-AT-VAR VAL) FUNCTION · src

∀ :A :B. MonadIo :B ⇒ (:A → (:B (AtVar :A)))

Create a new AtVar containing `val`.

(MODIFY ATM F) FUNCTION · src

∀ :A :B. (MonadIo :B) (Exceptions :B) ⇒ ((AtVar :A) → (:A → :A) → (:B :A))

Atomically modify `atm` by applying `f` and return the new value. `f` must be a pure function. If `f` throws an error, `atm` will be unchanged and the error will be handleable via `Exceptions`. Concurrent: - WARNING: `f` will be retried each time the calling thread loses the race to update `atm`, so `f` must be pure.

(WRITE ATM VAL) FUNCTION · src

∀ :A :B. MonadIo :B ⇒ ((AtVar :A) → :A → (:B Unit))

Atomically write a new value to `atm`.

(READ ATM) FUNCTION · src

∀ :A :B. MonadIo :B ⇒ ((AtVar :A) → (:B :A))

Atomically read the value from `atm`.

(PUSH ATM ELT) FUNCTION · src

∀ :A :B. MonadIo :B ⇒ ((AtVar (List :A)) → :A → (:B (List :A)))

Atomically push a value onto an atomic list. Returns the new list.

(POP ATM) FUNCTION · src

∀ :A :B. MonadIo :B ⇒ ((AtVar (List :A)) → (:B (Optional :A)))

Atomically pop and retrieve the head of an atomic list.


Package IO/CONC/MVAR

Structs

MChan :A STRUCT · src

A synchronized FIFO queue to pass data directionally between threads.

Instances

MVar :A STRUCT · src

A synchronized container that can be empty or hold an :a. All critical MVar operations are masked. However, irresponsible stopping could still cause deadlocks and other race conditions.

Instances

Values

(TAKE-MVAR-MASKED-WITH STRATEGY MVAR) FUNCTION · src

∀ :A :B :C :D. Threads :A :B :D ⇒ (TimeoutStrategy → (MVar :C) → (:D :C))

Take a value from an MVar, blocking until one is available. Concurrent: - WARNING: Leaves the thread masked when returns to protect caller's critical regions based on consuming and restoring MVar to a valid state. See MChan for an example. - Blocks while the MVar is empty - Read-consumers (including `take-mvar-masked`) are woken individual on succesfull puts, in order of acquisition - On succesful take, one blocking writer is woken in order of acquisition

(TRY-TAKE-MVAR-MASKED MVAR) FUNCTION · src

∀ :A :B :C :D. Threads :A :B :D ⇒ ((MVar :C) → (:D (Optional :C)))

Attempt to immediately take a value from an MVar. Returns None if empty. Concurrent: - WARNING: Leaves the thread masked when returns to protect caller's critical regions based on consuming and restoring MVar to a valid state. See MChan for an example. - Can briefly block while waiting to empty the MVar, if contended - On succesful take, one blocking writer is woken in order of acquisition

(TAKE-MVAR-MASKED MVAR) FUNCTION · src

∀ :A :B :C :D. Threads :A :B :D ⇒ ((MVar :C) → (:D :C))

Take a value from an MVar, blocking until one is available. Concurrent: - WARNING: Leaves the thread masked when returns to protect caller's critical regions based on consuming and restoring MVar to a valid state. See MChan for an example. - Blocks while the MVar is empty - Read-consumers (including `take-mvar-masked`) are woken individual on succesfull puts, in order of acquisition - On succesful take, one blocking writer is woken in order of acquisition

(TAKE-MVAR-WITH STRATEGY MVAR) FUNCTION · src

∀ :A :B :C :D. Threads :A :B :D ⇒ (TimeoutStrategy → (MVar :C) → (:D :C))

Take a value from an MVar, blocking until one is available. Concurrent: - Blocks while the MVar is empty - Read-consumers (including `take-mvar`) are woken individual on succesful puts, in order of acquisition - On succesful take, one blocking writer is woken in order of acquisition

(SWAP-MVAR-WITH STRATEGY MVAR NEW-VAL) FUNCTION · src

∀ :A :B :C :D. Threads :A :B :D ⇒ (TimeoutStrategy → (MVar :C) → :C → (:D :C))

Atomically replace the value in an MVar and return the old value. Concurrent: - Blocks while the MVar is empty - Wakes the next blocking read-consumer when `swap-mvar` completes

(READ-MVAR-WITH STRATEGY MVAR) FUNCTION · src

∀ :A :B :C :D. Threads :A :B :D ⇒ (TimeoutStrategy → (MVar :C) → (:D :C))

Read a value from an MVar, blocking until one is available. Does not consume value. Concurrent: - Blocks while the MVar is empty - Blocking read-non-consumers (including `read-mvar`) are woken simultaneously on succesful put. Data is handed directly to woken readers, which don't contend on mvar.

NEW-EMPTY-MVAR VALUE · src

∀ :A :B :C :D. Threads :A :B :C ⇒ (:C (MVar :D))

Create a new empty MVar.

NEW-EMPTY-CHAN VALUE · src

∀ :A :B :C :D. Threads :A :B :C ⇒ (:C (MChan :D))

Create a new empty channel.

(TRY-TAKE-MVAR MVAR) FUNCTION · src

∀ :A :B :C :D. Threads :A :B :D ⇒ ((MVar :C) → (:D (Optional :C)))

Attempt to immediately take a value from an MVar. Returns None if empty. Concurrent: - Can briefly block while waiting to empty the MVar, if contended - On succesful take, one blocking writer is woken in order of acquisition

(TRY-READ-MVAR MVAR) FUNCTION · src

∀ :A :B :C :D. Threads :A :B :D ⇒ ((MVar :C) → (:D (Optional :C)))

Attempt to immediately read a value from an MVar. Returns None if empty.

(PUT-MVAR-WITH STRATEGY MVAR VAL) FUNCTION · src

∀ :A :B :C :D. Threads :A :B :D ⇒ (TimeoutStrategy → (MVar :C) → :C → (:D Unit))

Fill an empty MVar, blocking until it becomes empty. Concurrent: - Blocks while the MVar is full - Writers (including `put-mvar`) are woken individual on succesful takes in order of acquisition - On succesful put, blocking read-consumers are woken individually in order of acquisition - On succesful put, all blocking read-non-consumers are woken simultaneously. New data is handed directly to woken read-non-consumers so they don't contend on the MVar.

(POP-CHAN-WITH STRATEGY CHAN) FUNCTION · src

∀ :A :B :C :D. Threads :A :B :D ⇒ (TimeoutStrategy → (MChan :C) → (:D :C))

Pop the front value in CHAN. Blocks while CHAN is empty.

(IS-EMPTY-MVAR MVAR) FUNCTION · src

∀ :A :B :C :D. Threads :A :B :D ⇒ ((MVar :C) → (:D Boolean))

Return True if the MVar is currently empty.

(TRY-PUT-MVAR MVAR VAL) FUNCTION · src

∀ :A :B :C :D. Threads :A :B :D ⇒ ((MVar :C) → :C → (:D Boolean))

Attempt to immediately put a value into an MVar. Returns True if succeeded. Concurrent: - Can briefly block while waiting to fill the MVar, if contended - On succesful put, blocking read-consumers are woken individually in order of acquisition - On succesful put, all blocking read-non-consumers are woken simultaneously. New data is handed directly to woken read-non-consumers so they don't contend on the MVar.

(TRY-POP-CHAN CHAN) FUNCTION · src

∀ :A :B :C :D. Threads :A :B :D ⇒ ((MChan :C) → (:D (Optional :C)))

Attempt to pop the front value in CHAN. Does not block.

(WITH-MVAR MVAR OP) FUNCTION · src

∀ :A :B :C :D :E :F :G. (UnliftIo :E :A) (LiftTo :E :G) (Threads :B :C :A) ⇒ ((MVar :D) → (:D → (:E :F)) → (:G :F))

Run an operation with the value from an MVar, blocking until one is available. Restore the MVar value and return the result of the operation. WARNING: If the computation raises an unhandled exception or is stopped, leaves the MVar empty! Concurrent: - WARNING: Does not mask during the computation. To ensure completion, caller must mask - Blocks while the MVar is empty - Inherits notify semantics from `put-mvar` - Does not leave the MVar locked during the computation. Thus, other threads can put the MVar during the computation and force `with-mvar` to block until empty.

(TAKE-MVAR MVAR) FUNCTION · src

∀ :A :B :C :D. Threads :A :B :D ⇒ ((MVar :C) → (:D :C))

Take a value from an MVar, blocking until one is available. Concurrent: - Blocks while the MVar is empty - Read-consumers (including `take-mvar`) are woken individual on succesful puts, in order of acquisition - On succesful take, one blocking writer is woken in order of acquisition

(SWAP-MVAR MVAR NEW-VAL) FUNCTION · src

∀ :A :B :C :D. Threads :A :B :D ⇒ ((MVar :C) → :C → (:D :C))

Atomically replace the value in an MVar and return the old value. Concurrent: - Blocks while the MVar is empty - Wakes the next blocking read-consumer when `swap-mvar` completes

(READ-MVAR MVAR) FUNCTION · src

∀ :A :B :C :D. Threads :A :B :D ⇒ ((MVar :C) → (:D :C))

Read a value from an MVar, blocking until one is available. Does not consume value. Concurrent: - Blocks while the MVar is empty - Blocking read-non-consumers (including `read-mvar`) are woken simultaneously on succesful put. Data is handed directly to woken readers, which don't contend on mvar.

(PUSH-CHAN CHAN VAL) FUNCTION · src

∀ :A :B :C :D. Threads :A :B :D ⇒ ((MChan :C) → :C → (:D Unit))

Push VAL onto CHAN.

(PUT-MVAR MVAR VAL) FUNCTION · src

∀ :A :B :C :D. Threads :A :B :D ⇒ ((MVar :C) → :C → (:D Unit))

Fill an empty MVar, blocking until it becomes empty. Concurrent: - Blocks while the MVar is full - Writers (including `put-mvar`) are woken individual on succesful takes in order of acquisition - On succesful put, blocking read-consumers are woken individually in order of acquisition - On succesful put, all blocking read-non-consumers are woken simultaneously. New data is handed directly to woken read-non-consumers so they don't contend on the MVar.

(POP-CHAN CHAN) FUNCTION · src

∀ :A :B :C :D. Threads :A :B :D ⇒ ((MChan :C) → (:D :C))

Pop the front value in CHAN. Blocks while CHAN is empty.

(NEW-MVAR VAL) FUNCTION · src

∀ :A :B :C :D. Threads :A :B :D ⇒ (:C → (:D (MVar :C)))

Create a new MVar containing VAL.

(WITH-MVAR_) FUNCTION · src

∀ :A :B :C. (Threads IoRuntime IoThread :C) (LiftTo IO :C) ⇒ ((MVar :A) → (:A → (IO :B)) → (:C :B))

Run an operation with the value from an MVar, blocking until one is available. Restore the MVar value and return the result of the operation. WARNING: If the computation raises an unhandled exception or is stopped, leaves the MVar empty! Concurrent: - WARNING: Does not mask during the computation. To ensure completion, caller must mask - Blocks while the MVar is empty - Inherits notify semantics from `put-mvar` - Does not leave the MVar locked during the computation. Thus, other threads can put the MVar during the computation and force `with-mvar` to block until empty.


Macros

DO-WITH-MVAR_ ((SYM MVAR) &BODY BODY) MACRO

Run an operation with the value from an MVar, blocking until one is available. Stores the result of the operation in the MVar and returns. WARNING: If the computation raises an unhandled exception or is stopped, leaves the MVar empty! Concurrent: - WARNING: Does not mask during the computation. To ensure completion, caller must mask - Blocks while the MVar is empty - Inherits notify semantics from `put-mvar` - Does not leave the MVar locked during the computation. Thus, other threads can put the MVar during the computation and force `with-mvar` to block until empty.


Package IO/CONC/GROUP

Structs

ConcurrentGroup :A :B STRUCT · src

Handles masking, stopping, and awaiting a group of Concurrents as a unit. ConcurrentGroup does not pass messages/data. For more structured uses, see WorkerPool. ConcurrentGroup provides the following guarantees: * Masking/unmasking the group is atomic. If another thread attempts to stop the group, it will either stop all of the Concurrents or none of them. * Stopping the group sends the stop signal to all of the enclosed Concurrents. * Awaiting the group blocks until all of the enclosed Concurrents have completed. * Awaiting the group will error if any one of the enclosed Concurrents errored. * Calling unmask-finally on the group runs the callback on each Concurrent separately, not once on the thread calling (unmask-finally). ConcurrentGroup's guarantees are only valid if management of the enclosed Concurrents is done through the group. For example, if one thread tries to mask the group while another thread tries to stop one of the individual Concurrents in the group, then the second thread might stop the individual Concurrent before the first thread has a chance to mask it. Concurrent: - The `(Concurrent ConcurrentGroup :a)' instance masks `stop`, `mask`, `unmask`, and `unmask-finally` to guarantee atomicity of the enclosed Concurrents - `await` is not masked

Instances

Values

(ENCLOSE-GROUP CONCURRENTS) FUNCTION · src

∀ :A :B :C :D :E. (Threads :A :B :D) (Concurrent :C :E) ⇒ ((List :C) → (:D (ConcurrentGroup :C :E)))

Enclose already forked Concurrents in a ConcurrentGroup. Warning: After calling, the enclosed Concurrents should only be managed through the group.

(FORK-GROUP FORK-CONCURRENTS) FUNCTION · src

∀ :A :B :C :D :E. (Threads :A :B :C) (Concurrent :D :E) ⇒ ((List (:C :D)) → (:C (ConcurrentGroup :D :E)))

Run a list of IO operations that each forks a Concurrent. Enclose the forked Concurrents in a ConcurrentGroup. Concurrent: - Does not mask the forking operation, so it is possible to partially fork if stopped. To guarantee forking completion, caller should mask the call to `fork-group`.


Package IO/CONC/STM

Types

TVar TYPE · src

A Transaction Variable that can be read and modified inside an STM transaction.

Instances

STM TYPE · src

A transaction that can be run using `run-tx`.

Instances

Values

(MODIFY-SWAP-TVAR TVAR F) FUNCTION · src

∀ :A :B. MonadIo :B ⇒ ((TVar :A) → (:A → :A) → ((STM :B) :A))

Modify a mutable variable inside an atomic transaction. Returns the old value.

(MODIFY-TVAR TVAR F) FUNCTION · src

∀ :A :B. MonadIo :B ⇒ ((TVar :A) → (:A → :A) → ((STM :B) :A))

Modify a mutable variable inside an atomic transaction. Returns the new value.

(WRITE-TVAR TVAR VAL) FUNCTION · src

∀ :A :B. MonadIo :B ⇒ ((TVar :A) → :A → ((STM :B) Unit))

Write to a mutable variable inside an atomic transaction.

(RETRY-WITH STRATEGY) FUNCTION · src

∀ :A :B. MonadIo :A ⇒ (TimeoutStrategy → ((STM :A) :B))

Retry the current operation because the observed state is invalid. Waits for a write transaction to commit somewhere else, and then tries this transaction again. This is useful if the transaction needs to wait for other threads to update the data before it can continue. For example, if the transaction reads from a (TVar Queue) and the queue is empty, it must wait until another thread pushes onto the queue before it can continue. Concurrent: - When the transaction runs, executing retry will abort the transaction and sleep the thread. The thread will sleep until any relevant write transaction commits to the STM, when the retrying thread will wake and retry its transaction. A write transaction only triggers a retry if it writes to a TVar that was read before `retry` was called. - Will timeout depending on strategy.

(SWAP-TVAR TVAR NEW-VAL) FUNCTION · src

∀ :A :B. MonadIo :B ⇒ ((TVar :A) → :A → ((STM :B) :A))

Swap the value of a mutable variable inside an atomic transaction. Returns the old value.

(READ-TVAR TVAR) FUNCTION · src

∀ :A :B. MonadIo :B ⇒ ((TVar :A) → ((STM :B) :A))

Read a mutable variable inside an atomic transaction.

(NEW-TVAR VAL) FUNCTION · src

∀ :A :B. MonadIo :B ⇒ (:A → (:B (TVar :A)))

Create a mutable variable that can be used inside an atomic transaction.

(OR-ELSE TX-A TX-B) FUNCTION · src

∀ :A :B. MonadIo :A ⇒ (((STM :A) :B) → ((STM :A) :B) → ((STM :A) :B))

Run TX-A. If it signals a retry, run TX-b. If both transactions signal a retry, then the entire transaction retries.

(RUN-TX TX) FUNCTION · src

∀ :A :B :C :D. (Threads :A :B :C) (Exceptions :C) ⇒ (((STM :C) :D) → (:C :D))

Run an atomic transaction. If the transaction raises an exception, the transaction is aborted and the exception is re-raised. WARNING: The STM can abort and re-run the transaction repeatedly, until it completes with a consistent snapshot of the data. Therefore, TX must be pure.

RETRY VALUE · src

∀ :A :B. MonadIo :A ⇒ ((STM :A) :B)

Retry the current operation because the observed state is invalid. Waits for a write transaction to commit somewhere else, and then tries this transaction again. This is useful if the transaction needs to wait for other threads to update the data before it can continue. For example, if the transaction reads from a (TVar Queue) and the queue is empty, it must wait until another thread pushes onto the queue before it can continue. Concurrent: - When the transaction runs, executing retry will abort the transaction and sleep the thread. The thread will sleep until any relevant write transaction commits to the STM, when the retrying thread will wake and retry its transaction. A write transaction only triggers a retry if it writes to a TVar that was read before `retry` was called.


Macros

DO-RUN-TX (&BODY BODY) MACRO

Run an atomic transaction. If the transaction raises an exception, the transaction is aborted and the exception is re-raised. WARNING: The STM can abort and re-run the transaction repeatedly, until it completes with a consistent snapshot of the data. Therefore, TX must be pure.


Package IO/CONC/MCHAN-SCHEDULER

Types

MChanScheduler TYPE · src

An MChanScheduler uses a single MChan internally to manage tasks. Producers submit tasks onto the end of the MChan. Worker threads pop items, one-by-one, from the front of the MChan. MChanScheduler is unbounded.

Instances

Values

NEW-MCHAN-SCHEDULER VALUE · src

∀ :A :B :C :D. Threads :A :B :C ⇒ (:C (MChanScheduler :D))

Package IO/CONC/WORKER-POOL

Structs

WorkerPool :A :B :C STRUCT · src

A pool of worker threads that execute jobs submitted to the pool.

Instances

Values

(REQUEST-SHUTDOWN POOL) FUNCTION · src

∀ :A :B :C :D :E. (Threads :A :D :E) (Exceptions :E) (Scheduler :B) ⇒ ((((WorkerPool :B) :C) :D) → (:E Unit))

Request a shutdown. The threads in the pool will shutdown when all of the jobs already in the queue are completed. To immediately stop the threads, use `stop`.

(NEW-WORKER-POOL N-THREADS SCHEDULER) FUNCTION · src

∀ :A :B :C :D :E. (Threads :A :E :D) (UnliftIo :C :C) (Threads :A :E :C) (Exceptions :C) (Exceptions :D) (Concurrent :E Unit) (LiftIo :C :D) (Scheduler :B) ⇒ (UFix → (:B (Optional (:C Unit))) → (:D (((WorkerPool :B) :C) :E)))

Create a new worker pool. Automatically forks N-THREADS worker threads.

(SUBMIT-JOB POOL JOB) FUNCTION · src

∀ :A :B :C :D :E :F :G. (UnliftIo :E :C) (LiftTo :E :G) (Threads :A :D :C) (Exceptions :C) (Scheduler :B) ⇒ ((((WorkerPool :B) :C) :D) → (:E :F) → (:G Unit))

Submit a job to the worker pool. Any jobs submitted after a shutdown request will be ignored. Concurrent: - If the pool's scheduler is backed by a bounded data structure, then this can block while the scheduler is full.

(NEW-WORKER-POOL_) FUNCTION · src

∀ :A :B. (Threads IoRuntime IoThread :B) (Exceptions :B) (LiftIo IO :B) (Scheduler :A) ⇒ (UFix → (:A (Optional (IO Unit))) → (:B (((WorkerPool :A) IO) IoThread)))

(SUBMIT-JOB_) FUNCTION · src

∀ :A :B :C. (Threads IoRuntime IoThread :C) (LiftTo IO :C) (Scheduler :A) ⇒ ((((WorkerPool :A) IO) IoThread) → (IO :B) → (:C Unit))


Package IO/CONC/RING-BUFFER

Types

RingBufferScheduler TYPE · src

A RingBufferScheduler uses a single RingBuffer internally to manage tasks. MChanScheduler is bounded.

Instances

SchedulerError TYPE · src

Instances

Structs

RingBuffer :A STRUCT · src

A bounded FIFO Multi-Producer, Multi-Consumer Queue implemented as a RingBuffer.

Instances

Values

(NEW-RING-BUFFER-SCHEDULER CAPACITY) FUNCTION · src

∀ :A :B :C :D. (Threads :A :B :C) (Exceptions :C) ⇒ (UFix → (:C (RingBufferScheduler :D)))

(NEW-RING-BUFFER CAPACITY) FUNCTION · src

∀ :A :B :C :D. Threads :A :B :C ⇒ (UFix → (:C (RingBuffer :D)))

Create a new ring buffer with the given capacity.

(ENQUEUE-WITH ELT STRATEGY BUFFER) FUNCTION · src

∀ :A :B :C :D. Threads :A :B :D ⇒ (:C → TimeoutStrategy → (RingBuffer :C) → (:D Unit))

Add ELT to BUFFER. Concurrent: - Can block acquiring lock on buffer. - If full, blocks until BUFFER is not full, possibly timing out based on STRATEGY.

(DEQUEUE-WITH STRATEGY BUFFER) FUNCTION · src

∀ :A :B :C :D. Threads :A :B :D ⇒ (TimeoutStrategy → (RingBuffer :C) → (:D :C))

Pop an element from BUFFER. Concurrent: - Can block briefly while acquiring lock on buffer. - If empty, blocks until BUFFER is not empty.

(TRY-ENQUEUE ELT BUFFER) FUNCTION · src

∀ :A :B :C :D. Threads :A :B :D ⇒ (:C → (RingBuffer :C) → (:D Boolean))

Attempt to add ELT to BUFFER. Returns True if equeue succeeded, False otherwise. Concurrent: Can block acquiring lock on buffer.

(ENQUEUE ELT BUFFER) FUNCTION · src

∀ :A :B :C :D. Threads :A :B :D ⇒ (:C → (RingBuffer :C) → (:D Unit))

Add ELT to BUFFER. Concurrent: - Can block acquiring lock on buffer. - If full, blocks until BUFFER is not full.

(DEQUEUE BUFFER) FUNCTION · src

∀ :A :B :C :D. Threads :A :B :D ⇒ ((RingBuffer :C) → (:D :C))

Pop an element from BUFFER. Concurrent: - Can block briefly while acquiring lock on buffer. - If empty, blocks until BUFFER is not empty.


Package IO/IO-ALL


Package IO/STUBS/TERM

Types

TermStubM TYPE · src

TermStub TYPE · src


Values

(RUN-TERM-STUBM OPM READ-LINE-INPUTS) FUNCTION · src

∀ :A :B. Monad :A ⇒ ((((FreeT TermStubF) :A) :B) → (List String) → (:A (Tuple (List String) :B)))

(RUN-TERM-STUB STUB-OP READ-LINE-INPUTS) FUNCTION · src

∀ :A. ((((FreeT TermStubF) Identity) :A) → (List String) → (Tuple (List String) :A))