synchronized<T> method

  1. @override
Future<T> synchronized<T>(
  1. FutureOr<T> func(), {
  2. Duration? timeout,
})
override

Executes computation when lock is available.

Only one asynchronous block can run while the lock is retained.

If timeout is specified, it will try to grab the lock and will not call the computation callback and throw a TimeoutExpection is the lock cannot be grabbed in the given duration.

Implementation

@override
Future<T> synchronized<T>(FutureOr<T> Function() func,
    {Duration? timeout}) async {
  // Handle late synchronized section warning
  final level = innerLevel;

  // Check that we are still in the proper block
  // zones could run outside the block so it could lead to an unexpected behavior
  if (level >= innerLocks.length) {
    throw StateError(
        'This can happen if an inner synchronized block is spawned outside the block it was started from. Make sure the inner synchronized blocks are properly awaited');
  }
  final lock = innerLocks[level];

  return lock.synchronized(() async {
    innerLocks.add(BasicLock());
    try {
      var result = runZoned(() {
        return func();
      }, zoneValues: {this: level + 1});
      if (result is Future) {
        return await result;
      } else {
        return result;
      }
    } finally {
      innerLocks.removeLast();
    }
  }, timeout: timeout);
}