protect<T> method
Runs action once every earlier critical section has finished and
returns its result.
The lock is released whether action completes or throws (synchronously
or asynchronously); errors propagate to the caller.
Implementation
Future<T> protect<T>(FutureOr<T> Function() action) {
final previous = _tail;
final released = Completer<void>();
_tail = released.future;
_pending++;
return previous.then((_) => action()).whenComplete(() {
_pending--;
released.complete();
});
}