release method
void
release()
Releases one permit; hands it directly to the next waiter if any, otherwise returns it to the available pool. Audited: 2026-06-12 11:26 EDT
Implementation
void release() {
// Direct hand-off: when a waiter is queued the permit transfers to it
// WITHOUT touching `_available` (the slot was never freed to the pool). Only
// increment when there is no waiter to take the permit.
if (_waiters.isNotEmpty) {
_waiters.removeAt(0)();
} else {
// Guard the permit invariant: with no waiter and the pool already full,
// this release has no matching acquire. Incrementing would push
// `_available` above `permits` and let the semaphore admit more than
// `permits` concurrent holders forever. Fail loud instead of silently
// corrupting the count.
if (_available >= permits) {
throw StateError('release() called without a matching acquire() (permits: $permits)');
}
_available++;
}
}