import 'dart:async'; /// Async mutex to guarantee actions are performed sequentially and do not interleave class AsyncMutex { Future _running = Future.value(null); int _enqueued = 0; get enqueued => _enqueued; /// Execute [operation] exclusively, after any currently running operations. /// Returns a [Future] with the result of the [operation]. Future<T> run<T>(Future<T> Function() operation) { final completer = Completer<T>(); _enqueued++; _running.whenComplete(() { _enqueued--; completer.complete(Future<T>.sync(operation)); }); return _running = completer.future; } }