import 'dart:async'; import 'dart:collection'; import 'dart:ui'; /// A simple Mutex implementation using a [Completer]. class Mutex { final _completerQueue = Queue>(); /// Runs the given [run] function-block in a thread-safe/blocked zone. A convenient `unlock()` /// is provided, which can be called anywhere to signal re-entry. FutureOr lockAndRun({ required FutureOr Function(VoidCallback unlock) run, }) async { final completer = Completer(); _completerQueue.add(completer); if (_completerQueue.first != completer) { await _completerQueue.removeFirst().future; } final value = await run(completer.complete); return value; } /// Allows listening to the completion status of the last worker process to be released. Future get lastOperationCompletionAwaiter => _completerQueue.isNotEmpty ? _completerQueue.last.future : Future.value(); }