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 run(Future Function() operation) { final completer = Completer(); _enqueued++; _running.whenComplete(() { _enqueued--; completer.complete(Future.sync(operation)); }); return _running = completer.future; } }