nupp.suspension.host
Deciding what runs while something waits.
nupp.suspension is what a library parks through. This is the other side: what a host installs to answer those parks, and what a scheduler needs to drive them. The two are separate because the two jobs are. A library never installs a handler, and a host never subscribes to a readiness source, so neither has to read past the other's operations to find its own.
local host = require("nupp.suspension.host")
local function application(): nil
with installation = host.install(frameHandler) do
work()
end
endinstall puts a handler on the current coroutine for the extent of the with. Driving the readiness pumps while it waits is nupp.suspension's poll: the pumps are registered through that module and drained through it, by a scheduler here or by an embedding host that never installs a handler at all. create makes a coroutine that inherits the handler, so work started inside a handled extent is handled too.
A driver stands in front of a host rather than being one: a task scope opened in a frame installs one so the frame's own waits keep its children running. installDriver says so, delegatedPark and delegatedCanPark capture the handler it displaces so what it cannot satisfy goes outward, derive builds the wait to hand there, and the turn budget bounds how long it may run before it owes its host a turn.
See Suspension for the handler contract and a worked frame handler.
Module contents
Types
| Type | Kind | Description |
|---|---|---|
Handler | record | What a host installs to answer suspensions. |
Installed | record | An installed handler, and the obligation to put back what it displaced. |
Waiting | record | What a park exposes to the handler driving it. |
Types#
Handlerrecord#
record Handler ...What a host installs to answer suspensions.
Members
| Name | Kind | Description |
|---|---|---|
park | method | Parks or drives this Waiting; cleanup cancels the subscription. |
canPark | method | Reports whether this handler can park the current execution. |
shutdown | method | Releases scheduling state owned by this handler. |
parkmethod#
Parks or drives this Waiting; cleanup cancels the subscription.
Arguments
| Name | Type | Description |
|---|---|---|
self | Handler | |
waiting | Waiting | |
cleanup | function(): nil |
Returns
| Type | Description |
|---|---|
nil |
Installedrecord#
An installed handler, and the obligation to put back what it displaced.
Members
| Name | Kind | Description |
|---|---|---|
close | method | Restores the outer handler and settles every park this installation accepted, without suspending. |
handler | field | Handler supplied by the caller. |
Waitingrecord#
record Waiting ...What a park exposes to the handler driving it.
Members
| Name | Kind | Description |
|---|---|---|
ready | method | Reports whether the subscription has settled. |
onResume | method | Registers a wake callback for the waiting scheduler. |
operation | field | Diagnostic operation name supplied to suspend. |
readymethod#
ready: function(self: Waiting): booleanReports whether the subscription has settled.
Arguments
| Name | Type | Description |
|---|---|---|
self | Waiting |
Returns
| Type | Description |
|---|---|
boolean |
onResumemethod#
onResume: function(self: Waiting, wake: function(): nil): nilRegisters a wake callback for the waiting scheduler.
Settle-safe: where the wait has already settled, wake is called before this returns rather than stored. A handler may therefore arm once and then yield until ready returns true, without a recheck loop around the arming.
Arguments
| Name | Type | Description |
|---|---|---|
self | Waiting | |
wake | function(): nil |
Returns
| Type | Description |
|---|---|
nil |