twonly-app/lib/src/utils/exclusive_access.utils.dart

51 lines
1.3 KiB
Dart

import 'dart:async';
import 'dart:io';
import 'package:mutex/mutex.dart';
import 'package:twonly/globals.dart';
Future<T> exclusiveAccess<T>({
required String lockName,
required Future<T> Function() action,
required Mutex mutex,
}) async {
final lockFile = File('${AppEnvironment.cacheDir}/$lockName.lock');
return mutex.protect(() async {
var lockAcquired = false;
while (!lockAcquired) {
try {
lockFile.createSync(exclusive: true);
lockAcquired = true;
} on FileSystemException catch (e) {
final isExists = e is PathExistsException || e.osError?.errorCode == 17;
if (!isExists) {
break;
}
try {
final stat = lockFile.statSync();
if (stat.type != FileSystemEntityType.notFound) {
final age = DateTime.now().difference(stat.modified).inSeconds;
if (age > 10) {
lockFile.deleteSync();
continue;
}
}
} catch (_) {}
await Future.delayed(const Duration(milliseconds: 50));
} catch (_) {
break;
}
}
try {
return await action();
} finally {
if (lockAcquired) {
try {
if (lockFile.existsSync()) {
lockFile.deleteSync();
}
} catch (_) {}
}
}
});
}