acquire method
Resolves when a slot is available.
Throws CancelledException when cancelToken is (or becomes) cancelled
while waiting; an already-admitted caller is unaffected.
Implementation
Future<void> acquire([CancelToken? cancelToken]) {
cancelToken?.throwIfCancelled();
if (_current < _max) {
_current++;
return Future<void>.value();
}
final completer = Completer<void>();
var settled = false;
void waiter() {
if (settled) return;
settled = true;
completer.complete();
}
_queue.add(waiter);
if (cancelToken != null) {
unawaited(
cancelToken.onCancel.then((_) {
if (settled) return;
settled = true;
_queue.remove(waiter);
completer.completeError(CancelledException(cancelToken.cancelReason));
// Nobody may await the future (caller raced away); never crash.
completer.future.ignore();
}),
);
}
return completer.future;
}