mirror of
https://github.com/velopack/velopack.git
synced 2025-10-25 15:19:22 +00:00
Align C# locking with rust
This commit is contained in:
@@ -458,21 +458,13 @@ namespace Velopack
|
||||
/// <summary>
|
||||
/// Acquires a globally unique mutex/lock for the current application, to avoid concurrent install/uninstall/update operations.
|
||||
/// </summary>
|
||||
protected virtual Mutex AcquireUpdateLock()
|
||||
protected virtual async Task<IDisposable> AcquireUpdateLock()
|
||||
{
|
||||
var mutexId = $"velopack-{AppId}";
|
||||
bool created = false;
|
||||
Mutex? mutex = null;
|
||||
try {
|
||||
mutex = new Mutex(false, mutexId, out created);
|
||||
} catch (Exception ex) {
|
||||
Log.Warn(ex, "Unable to acquire global mutex/lock.");
|
||||
created = false;
|
||||
}
|
||||
if (mutex == null || !created) {
|
||||
throw new Exception("Cannot perform this operation while another install/unistall operation is in progress.");
|
||||
}
|
||||
return mutex;
|
||||
var dir = Directory.CreateDirectory(Locator.PackagesDir!);
|
||||
var lockPath = Path.Combine(dir.FullName, ".velopack_lock");
|
||||
var fsLock = new FileLock(lockPath);
|
||||
await fsLock.LockAsync().ConfigureAwait(false);
|
||||
return fsLock;
|
||||
}
|
||||
|
||||
private static IUpdateSource CreateSimpleSource(string urlOrPath)
|
||||
|
||||
38
src/lib-csharp/Util/FileLock.cs
Normal file
38
src/lib-csharp/Util/FileLock.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Velopack.Util
|
||||
{
|
||||
internal class FileLock : IDisposable
|
||||
{
|
||||
private readonly string _filePath;
|
||||
private FileStream? _fileStream;
|
||||
private bool _locked;
|
||||
|
||||
public FileLock(string path)
|
||||
{
|
||||
_filePath = path;
|
||||
}
|
||||
|
||||
public async Task LockAsync()
|
||||
{
|
||||
if (_locked) {
|
||||
return;
|
||||
}
|
||||
|
||||
await IoUtil.RetryAsync(
|
||||
() => {
|
||||
_fileStream = new FileStream(_filePath, FileMode.Create, FileAccess.Read, FileShare.None, bufferSize: 1, FileOptions.DeleteOnClose);
|
||||
_locked = true;
|
||||
return Task.CompletedTask;
|
||||
});
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Interlocked.Exchange(ref this._fileStream, null)?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user