Description
Bounds concurrent work without owning or creating tasks. A Gate admits at most Capacity holders. Waiting uses a private protected entry, so lightweight tasks suspend cooperatively while native tasks use GNARL. Shutdown rejects new acquisitions, releases queued callers, and lets existing holders drain.
Acquire
procedure Acquire (Item : in out Gate; Accepted : out Boolean; Cleanup_Armed : access Boolean := null)
Wait for capacity or terminal shutdown. An accepted call transfers one permit; the caller must Release it.
Parameters
- Item
Gate from which to acquire one permit
- Accepted
True when a permit was acquired; False on shutdown
- Cleanup_Armed
Optional caller-owned obligation. It must be False on call and becomes True in the admission state cut on success.
Raised exceptions
- Program_Error
Cleanup_Armed is already True
Acquire_Result
type Acquire_Result is (Permit_Acquired, Gate_Full, Gate_Closed, Acquire_Timed_Out);
Result of a nonblocking or timed acquisition.
Enumeration literals
- Permit_Acquired
One permit is now held by the caller
- Gate_Full
A nonblocking attempt found no capacity
- Gate_Closed
Shutdown rejected the acquisition
- Acquire_Timed_Out
A timed attempt reached its deadline
Acquire_Wait_Source
procedure Acquire_Wait_Source (Item : in out Gate; FD : out Interfaces.C.int; Can_Acquire : out Boolean)
Borrow a descriptor for composing Try_Acquire with a descriptor wait. When Can_Acquire is False, FD becomes readable after a release or shutdown. Otherwise retry Try_Acquire immediately and FD is -1. The caller must not read or close FD, and Gate must outlive the wait.
Parameters
- Item
Gate that owns the borrowed descriptor
- FD
Borrowed readiness descriptor, or -1 when retry is ready
- Can_Acquire
Whether Try_Acquire can make progress immediately
Raised exceptions
- Program_Error
Wake descriptor creation fails
Active
function Active (Item : Gate) return Natural
Return the number of currently held permits.
Parameters
- Item
Gate to inspect
Return value
Current active permit count
Await_Drained
procedure Await_Drained (Item : in out Gate)
Wait until shutdown has begun and all permits have been released.
Parameters
- Item
Gate whose holders must drain
Gate
type Gate (Capacity : Positive) is tagged limited private;
Thread-safe bounded admission controller. The Gate must outlive every holder and every borrowed wake descriptor. Capacity is the maximum number of active permits. Optional Cleanup_Armed parameters publish a controlled caller's obligation in the same cut as permit ownership. Descriptor initialization, signaling, and EINTR retries occur outside the private protected state lock. These operations must not be called from another protected action. Borrowers must not close a wake descriptor. A failed drain after admission does not revoke or hide the transferred permit; the caller's guard retries before it leaves scope.
Record fields
- Capacity
Maximum number of active permits
Release
procedure Release (Item : in out Gate; Cleanup_Armed : access Boolean := null)
Release a held permit. A wake error may raise after release commits; Cleanup_Armed, when supplied, is cleared in the state cut.
Parameters
- Item
Gate to which the permit is returned
- Cleanup_Armed
Optional caller-owned obligation; it must be True on call and becomes False when the permit is released.
Raised exceptions
- Program_Error
No permit is active, Cleanup_Armed is False, or an admission wake fails after release
Request_Shutdown
procedure Request_Shutdown (Item : in out Gate)
Publish terminal shutdown, then wake descriptor waiters. A wake error may raise Program_Error after shutdown has committed.
Parameters
- Item
Gate to shut down
Shutdown_Requested
function Shutdown_Requested (Item : Gate) return Boolean
Report whether terminal shutdown has begun.
Parameters
- Item
Gate to inspect
Return value
True once Request_Shutdown records terminal shutdown
Timed_Acquire
procedure Timed_Acquire
(Item : in out Gate;
Timeout : Duration;
Result : out Acquire_Result;
Cleanup_Armed : access Boolean := null)
Acquire within one relative deadline. Negative Timeout waits indefinitely and zero is an immediate attempt. Once the private entry accepts the call, acquisition wins over a simultaneous deadline. Cleanup_Armed is published in the state cut that transfers ownership; an aborted caller must use that obligation rather than the unavailable Result to decide whether it owes Release.
Parameters
- Item
Gate from which to acquire one permit
- Timeout
Relative deadline in seconds
- Result
Permit_Acquired, Gate_Closed, or Acquire_Timed_Out
- Cleanup_Armed
Optional caller-owned obligation. It must be False on call and becomes True when a permit is acquired.
Raised exceptions
- Program_Error
Cleanup_Armed is already True
Try_Acquire
procedure Try_Acquire
(Item : in out Gate; Result : out Acquire_Result; Cleanup_Armed : access Boolean := null)
Attempt admission without waiting.
Parameters
- Item
Gate from which to attempt one acquisition
- Result
Permit_Acquired, Gate_Full, or Gate_Closed
- Cleanup_Armed
Optional caller-owned obligation. It must be False on call and becomes True in the admission state cut on success.
Raised exceptions
- Program_Error
Cleanup_Armed is already True
Wait_Source
procedure Wait_Source (Item : in out Gate; FD : out Interfaces.C.int; Already_Requested : out Boolean)
Borrow a readable descriptor that becomes ready on shutdown. The caller must not close it and Gate must outlive the wait.
Parameters
- Item
Gate that owns the borrowed descriptor
- FD
Borrowed descriptor, or -1 after shutdown
- Already_Requested
Whether shutdown already started
Raised exceptions
- Program_Error
Wake descriptor creation fails
Waiting
function Waiting (Item : Gate) return Natural
Return the number of callers queued at Acquire.
Parameters
- Item
Gate to inspect
Return value
Current number of queued acquisition callers