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>
|
/// <summary>
|
||||||
/// Acquires a globally unique mutex/lock for the current application, to avoid concurrent install/uninstall/update operations.
|
/// Acquires a globally unique mutex/lock for the current application, to avoid concurrent install/uninstall/update operations.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected virtual Mutex AcquireUpdateLock()
|
protected virtual async Task<IDisposable> AcquireUpdateLock()
|
||||||
{
|
{
|
||||||
var mutexId = $"velopack-{AppId}";
|
var dir = Directory.CreateDirectory(Locator.PackagesDir!);
|
||||||
bool created = false;
|
var lockPath = Path.Combine(dir.FullName, ".velopack_lock");
|
||||||
Mutex? mutex = null;
|
var fsLock = new FileLock(lockPath);
|
||||||
try {
|
await fsLock.LockAsync().ConfigureAwait(false);
|
||||||
mutex = new Mutex(false, mutexId, out created);
|
return fsLock;
|
||||||
} 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IUpdateSource CreateSimpleSource(string urlOrPath)
|
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