public async Task <ICacheEntry> GetOrAddAsync(string key, Func <string, Stream, ICacheControl, Task> valueFactory, ICacheControl cacheControl, CancellationToken ct) { using (await _rwLock.ReadLockAsync()) { ICacheEntry found = GetInternal(key); if (!(found is EmptyCacheEntry)) { found.Ref(); // this entry remain valid after releasing the lock return(found); } } using (await _rwLock.WriteLockAsync()) { ICacheEntry found = GetInternal(key); if (!(found is EmptyCacheEntry)) { found.Ref(); // this entry remain valid after releasing the lock return(found); } var randomPath = await _fs.WriteAtomicAsync((sink, cancel) => valueFactory(key, sink, cacheControl), _cacheTmpPath, ct).ConfigureAwait(false); var tmpEntry = new DiskCacheEntry(key, randomPath, this); if (!cacheControl.NoStore) { SetInternal(key, tmpEntry); } var entry = GetInternal(key); entry.Ref(); return(entry); } }
public void TestBlockingAsync() { var l = new AsyncReaderWriterLock(); for (var i = 0; i < 2; i++) { var readReleaserTask = l.ReadLockAsync(); AssertEqualValue(() => l.CurrentReaders, 1, readReleaserTask); AssertTaskCompleted(readReleaserTask); var readReleaserTask2 = l.ReadLockAsync(); AssertEqualValue(() => l.CurrentReaders, 2, readReleaserTask2); AssertTaskCompleted(readReleaserTask2); var writeReleaserTask = l.WriteLockAsync(); AssertEqualValue(() => l.AcquiredWriteLock, true, writeReleaserTask); AssertEqualValue(() => l.Writing, false, writeReleaserTask); Assert.That(writeReleaserTask.IsCompleted, Is.False); readReleaserTask.Result.Dispose(); Assert.That(l.CurrentReaders, Is.EqualTo(1)); Assert.That(writeReleaserTask.IsCompleted, Is.False); readReleaserTask2.Result.Dispose(); Assert.That(l.CurrentReaders, Is.EqualTo(0)); AssertEqualValue(() => l.Writing, true, writeReleaserTask); AssertTaskCompleted(writeReleaserTask); readReleaserTask = l.ReadLockAsync(); AssertEqualValue(() => l.ReadersWaiting, 1, readReleaserTask); Assert.That(readReleaserTask.IsCompleted, Is.False); var writeReleaserTask2 = l.WriteLockAsync(); AssertEqualValue(() => l.WritersWaiting, 1, writeReleaserTask2); Assert.That(writeReleaserTask2.IsCompleted, Is.False); writeReleaserTask.Result.Dispose(); AssertEqualValue(() => l.WritersWaiting, 0, writeReleaserTask2); AssertEqualValue(() => l.Writing, true, writeReleaserTask2); Assert.That(readReleaserTask.IsCompleted, Is.False); AssertTaskCompleted(writeReleaserTask2); writeReleaserTask2.Result.Dispose(); AssertEqualValue(() => l.Writing, false, writeReleaserTask2); AssertEqualValue(() => l.ReadersWaiting, 0, readReleaserTask); AssertEqualValue(() => l.CurrentReaders, 1, readReleaserTask); AssertTaskCompleted(readReleaserTask); readReleaserTask.Result.Dispose(); Assert.That(l.ReadersWaiting, Is.EqualTo(0)); Assert.That(l.WritersWaiting, Is.EqualTo(0)); Assert.That(l.CurrentReaders, Is.EqualTo(0)); Assert.That(l.Writing, Is.False); } }
public async Task TestInvaildExitReadLockUsageAsync() { var l = new AsyncReaderWriterLock(); var readReleaser = await(l.ReadLockAsync()); var readReleaser2 = await(l.ReadLockAsync()); readReleaser.Dispose(); readReleaser2.Dispose(); Assert.Throws <InvalidOperationException>(() => readReleaser.Dispose()); Assert.Throws <InvalidOperationException>(() => readReleaser2.Dispose()); }
///<summary>Gets all files that directly depend on the specified file.</summary> public async Task <IEnumerable <string> > GetDirectDependentsAsync(string fileName) { fileName = Path.GetFullPath(fileName); using (await rwLock.ReadLockAsync()) { GraphNode fileNode; if (!nodes.TryGetValue(fileName, out fileNode)) { return(Enumerable.Empty <string>()); } return(fileNode.Dependents.Select(d => d.FileName)); } }
public void TestMixingSyncAndAsync() { var l = new AsyncReaderWriterLock(); var readReleaser = l.ReadLock(); Assert.That(l.CurrentReaders, Is.EqualTo(1)); var readReleaserTask = l.ReadLockAsync(); AssertEqualValue(() => l.CurrentReaders, 2, readReleaserTask); AssertTaskCompleted(readReleaserTask); readReleaser.Dispose(); Assert.That(l.CurrentReaders, Is.EqualTo(1)); readReleaserTask.Result.Dispose(); Assert.That(l.CurrentReaders, Is.EqualTo(0)); var writeReleaser = l.WriteLock(); Assert.That(l.AcquiredWriteLock, Is.True); var writeReleaserTask = l.WriteLockAsync(); AssertEqualValue(() => l.WritersWaiting, 1, writeReleaserTask); Assert.That(writeReleaserTask.IsCompleted, Is.False); readReleaserTask = Task.Run(() => l.ReadLock()); AssertEqualValue(() => l.ReadersWaiting, 1, readReleaserTask); Assert.That(readReleaserTask.IsCompleted, Is.False); var readReleaserTask2 = l.ReadLockAsync(); AssertEqualValue(() => l.ReadersWaiting, 2, readReleaserTask2); Assert.That(readReleaserTask2.IsCompleted, Is.False); writeReleaser.Dispose(); AssertEqualValue(() => l.WritersWaiting, 0, writeReleaserTask); AssertEqualValue(() => l.Writing, true, writeReleaserTask); AssertTaskCompleted(writeReleaserTask); Assert.That(readReleaserTask.IsCompleted, Is.False); Assert.That(readReleaserTask2.IsCompleted, Is.False); writeReleaserTask.Result.Dispose(); AssertEqualValue(() => l.CurrentReaders, 2, readReleaserTask); AssertEqualValue(() => l.ReadersWaiting, 0, readReleaserTask2); AssertTaskCompleted(readReleaserTask); AssertTaskCompleted(readReleaserTask2); }
public void TestWritePriorityOverReadAsync() { var l = new AsyncReaderWriterLock(); for (var i = 0; i < 2; i++) { var writeReleaser = l.WriteLock(); Assert.That(l.AcquiredWriteLock, Is.True); var readReleaserTask = l.ReadLockAsync(); AssertEqualValue(() => l.ReadersWaiting, 1, readReleaserTask); var writeReleaserTask = l.WriteLockAsync(); AssertEqualValue(() => l.WritersWaiting, 1, writeReleaserTask); writeReleaser.Dispose(); AssertEqualValue(() => l.WritersWaiting, 0, writeReleaserTask); AssertEqualValue(() => l.ReadersWaiting, 1, readReleaserTask); AssertTaskCompleted(writeReleaserTask); writeReleaserTask.Result.Dispose(); AssertEqualValue(() => l.ReadersWaiting, 0, readReleaserTask); AssertTaskCompleted(readReleaserTask); readReleaserTask.Result.Dispose(); } }
internal async Threading.Task AttachFileObserverEvent(string fileName) { if (!File.Exists(fileName)) { return; } fileName = Path.GetFullPath(fileName); using (await rwLock.ReadLockAsync()) { if (_watchedFiles.Contains(fileName)) { return; } } using (await rwLock.WriteLockAsync()) { _watchedFiles.Add(fileName); } _watcher = new FileSystemWatcher(); _watcher.Path = Path.GetDirectoryName(fileName); _watcher.Filter = Path.GetFileName(fileName); _watcher.NotifyFilter = NotifyFilters.Attributes | NotifyFilters.LastWrite | NotifyFilters.Size; _watcher.Changed += async(s, e) => await UpdateBundles(null, true); _watcher.EnableRaisingEvents = true; }
public void TestOperationAfterDisposeAsync() { var l = new AsyncReaderWriterLock(); l.Dispose(); Assert.ThrowsAsync <ObjectDisposedException>(() => l.ReadLockAsync()); Assert.ThrowsAsync <ObjectDisposedException>(() => l.WriteLockAsync()); }
public async Task ValueFactoryRequiresReadLockHeldByOther() { var lck = new AsyncReaderWriterLock(); var readLockAcquiredByOther = new AsyncManualResetEvent(); var writeLockWaitingByOther = new AsyncManualResetEvent(); var lazy = new AsyncLazy <object>( async delegate { await writeLockWaitingByOther; using (await lck.ReadLockAsync()) { return(new object()); } }); var writeLockTask = Task.Run(async delegate { await readLockAcquiredByOther; var writeAwaiter = lck.WriteLockAsync().GetAwaiter(); writeAwaiter.OnCompleted(delegate { using (writeAwaiter.GetResult()) { } }); writeLockWaitingByOther.Set(); }); // Kick off the value factory without any lock context. var resultTask = lazy.GetValueAsync(); using (await lck.ReadLockAsync()) { readLockAcquiredByOther.Set(); // Now request the lazy task again. // This would traditionally deadlock because the value factory won't // be able to get its read lock while a write lock is waiting (for us to release ours). // This unit test verifies that the AsyncLazy<T> class can avoid deadlocks in this case. await lazy.GetValueAsync(); } }
public void TestPartialReleasingReadLockAsync() { var l = new AsyncReaderWriterLock(); var readReleaserTask = l.ReadLockAsync(); AssertEqualValue(() => l.CurrentReaders, 1, readReleaserTask); AssertTaskCompleted(readReleaserTask); var readReleaserTask2 = l.ReadLockAsync(); AssertEqualValue(() => l.CurrentReaders, 2, readReleaserTask); AssertTaskCompleted(readReleaserTask2); var writeReleaserTask = l.WriteLockAsync(); AssertEqualValue(() => l.AcquiredWriteLock, true, writeReleaserTask); AssertEqualValue(() => l.Writing, false, writeReleaserTask); Assert.That(writeReleaserTask.IsCompleted, Is.False); var readReleaserTask3 = l.ReadLockAsync(); AssertEqualValue(() => l.ReadersWaiting, 1, readReleaserTask3); Assert.That(readReleaserTask3.IsCompleted, Is.False); readReleaserTask.Result.Dispose(); Assert.That(writeReleaserTask.IsCompleted, Is.False); Assert.That(readReleaserTask3.IsCompleted, Is.False); readReleaserTask2.Result.Dispose(); AssertEqualValue(() => l.Writing, true, writeReleaserTask); AssertEqualValue(() => l.ReadersWaiting, 1, readReleaserTask3); AssertTaskCompleted(writeReleaserTask); Assert.That(readReleaserTask3.IsCompleted, Is.False); writeReleaserTask.Result.Dispose(); AssertEqualValue(() => l.ReadersWaiting, 0, readReleaserTask3); AssertTaskCompleted(readReleaserTask3); }
public async Task AttachFileObserver(IBundleDocument document, string fileName, Func <string, bool, Task> updateBundle) { _document = document; _bundleFileName = document.FileName; fileName = Path.GetFullPath(fileName); if (!File.Exists(fileName)) { return; } _watcher = new FileSystemWatcher { Path = Path.GetDirectoryName(fileName), Filter = Path.GetFileName(fileName), //_watcher.NotifyFilter = NotifyFilters.Attributes | NotifyFilters.LastWrite | NotifyFilters.Size; NotifyFilter = NotifyFilters.Attributes | NotifyFilters.CreationTime | NotifyFilters.FileName | NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.Size }; using (await _rwLock.ReadLockAsync()) { if (WatchedFiles.ContainsKey(_bundleFileName) && WatchedFiles[_bundleFileName].Any(s => s.Item1.Equals(fileName, StringComparison.OrdinalIgnoreCase))) { return; } } _changeEvent = (_, __) => Changed(updateBundle); _watcher.Changed += _changeEvent; _watcher.Deleted += (_, __) => Deleted(fileName); if (_extensions.Any(e => fileName.EndsWith(e, StringComparison.OrdinalIgnoreCase))) { _watcher.Renamed += (_, renamedEventArgument) => Renamed(renamedEventArgument, updateBundle); } _watcher.EnableRaisingEvents = true; using (await _rwLock.WriteLockAsync()) { if (!WatchedFiles.ContainsKey(_bundleFileName)) { WatchedFiles.Add(_bundleFileName, new HashSet <Tuple <string, FileSystemWatcher> >()); } WatchedFiles[_bundleFileName].Add(new Tuple <string, FileSystemWatcher>(fileName, _watcher)); } }
public async Task <IEnumerable <Package> > GetInstalledPackages() { using (await Lock.ReadLockAsync()) { var choco = Lets.GetChocolatey().SetCustomLogging(new SerilogLogger(Logger, _progressService)); choco.Set( config => { config.CommandName = CommandNameType.list.ToString(); config.ListCommand.LocalOnly = true; }); return((await choco.ListAsync <PackageResult>()) .Select(package => GetMappedPackage(choco, package, _mapper, true)) .ToArray()); } }
private static async Task LockAsync( AsyncReaderWriterLock readWriteLock, Random random, LockStatistics lockStatistics, System.Action checkLockAction, Func <bool> canContinue, CancellationToken cancellationToken = default(CancellationToken)) { while (canContinue()) { var isRead = random.Next(100) < 80; var releaser = isRead ? await(readWriteLock.ReadLockAsync()) : await(readWriteLock.WriteLockAsync()); lock (readWriteLock) { if (isRead) { lockStatistics.ReadLockCount++; } else { lockStatistics.WriteLockCount++; } checkLockAction(); } await(Task.Delay(10, cancellationToken)); lock (readWriteLock) { releaser.Dispose(); if (isRead) { lockStatistics.ReadLockCount--; } else { lockStatistics.WriteLockCount--; } checkLockAction(); } } }
public async Task AttachFileObserver(string fileName, string bundleFile, Func <string, bool, Task> updateBundle) { fileName = Path.GetFullPath(fileName); if (!File.Exists(fileName)) { return; } _watcher = new FileSystemWatcher(); _watcher.Path = Path.GetDirectoryName(fileName); _watcher.Filter = Path.GetFileName(fileName); //_watcher.NotifyFilter = NotifyFilters.Attributes | NotifyFilters.LastWrite | NotifyFilters.Size; _watcher.NotifyFilter = NotifyFilters.Attributes | NotifyFilters.CreationTime | NotifyFilters.FileName | NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.Size; using (await rwLock.ReadLockAsync()) { if (_watchedFiles.ContainsKey(bundleFile) && _watchedFiles[bundleFile].Contains(fileName)) { return; } } using (await rwLock.WriteLockAsync()) { if (!_watchedFiles.ContainsKey(bundleFile)) { _watchedFiles.Add(bundleFile, new HashSet <string>()); } _watchedFiles[bundleFile].Add(fileName); } _watcher.Changed += async(s, e) => await updateBundle(bundleFile, false); _watcher.EnableRaisingEvents = true; }
public static async Task RunAsync(int id) { Console.WriteLine($"Run {id}"); await Task.Delay(1000); for (var i = 0; i < id * 2; i++) { using (await locker.ReadLockAsync()) { using (await consoleLock.EnterAsync()) { Interlocked.Increment(ref readers); Console.WriteLine($"Begin Read Loop {i + 1} Id {id} number of readers {readers}"); } await Task.Delay(1000); using (await consoleLock.EnterAsync()) { Interlocked.Decrement(ref readers); Console.WriteLine($"End Read Loop {i + 1} Id {id} number of readers {readers}"); } } } using (await locker.UpgradeableReadLockAsync()) { using (await consoleLock.EnterAsync()) { Interlocked.Increment(ref upgradeables); Console.WriteLine($"Begin Upgradeable Id {id} number of upgradeables {upgradeables}"); } await Task.Delay(1000); using (await consoleLock.EnterAsync()) { Console.WriteLine($"Wait Upgarde Id {id} number of upgradeables {upgradeables}"); } using (await locker.WriteLockAsync()) { using (await consoleLock.EnterAsync()) { Interlocked.Increment(ref writers); Console.WriteLine($"Begin Write Id {id} number of writers {writers}"); } await Task.Delay(1000); using (await consoleLock.EnterAsync()) { Interlocked.Decrement(ref writers); Console.WriteLine($"End Write ID {id} number of writers {writers}"); } } using (await consoleLock.EnterAsync()) { Interlocked.Decrement(ref upgradeables); Console.WriteLine($"End Upgradeable Id {id} number of upgradeables {upgradeables}"); } } }
public async Task <JoinRoomResult> JoinRoomAsync(string peerId, string connectionId, JoinRoomRequest joinRoomRequest) { using (await _peersLock.ReadLockAsync()) { if (!_peers.TryGetValue(peerId, out var peer)) { throw new PeerNotExistsException("JoinRoomAsync()", peerId); } CheckConnection(peer, connectionId); await _roomsLock.WaitAsync(); try { // Room 如果不存在则创建 if (!_rooms.TryGetValue(joinRoomRequest.RoomId, out var room)) { // Router media codecs. var mediaCodecs = _mediasoupOptions.MediasoupSettings.RouterSettings.RtpCodecCapabilities; // Create a mediasoup Router. var worker = _mediasoupServer.GetWorker(); var router = await worker.CreateRouterAsync(new RouterOptions { MediaCodecs = mediaCodecs }); if (router == null) { throw new Exception($"PeerJoinAsync() | Worker maybe closed."); } room = new Room(_loggerFactory, router, joinRoomRequest.RoomId, "Default"); _rooms[room.RoomId] = room; } var result = await peer.JoinRoomAsync(room); await peer.SetPeerInternalDataAsync(new SetPeerInternalDataRequest { InternalData = new Dictionary <string, object> { { Peer.RoleKey, joinRoomRequest.Role } } }); return(result); } catch (Exception ex) { _logger.LogError(ex, "JoinRoomAsync()"); throw; } finally { _roomsLock.Set(); } } }
public static AsyncReaderWriterLock.Awaitable ReadOnMainAsync() { return(_cs_main_async.ReadLockAsync()); }
public void Should_allow_multiple_read_locks_immediately_when_unlocked() { var readerTask1 = locker.ReadLockAsync(); var readerTask2 = locker.ReadLockAsync(); var readerTask3 = locker.ReadLockAsync(); readerTask1.IsCompleted.Should().BeTrue(); readerTask2.IsCompleted.Should().BeTrue(); readerTask3.IsCompleted.Should().BeTrue(); }
public async Task TestConcurrentReadWriteAsync() { var l = new AsyncReaderWriterLock(); for (var i = 0; i < 2; i++) { var writeReleaser = await(l.WriteLockAsync()); Assert.That(l.Writing, Is.True); var secondWriteSemaphore = new SemaphoreSlim(0); var secondWriteReleaser = default(AsyncReaderWriterLock.Releaser); var secondWriteThread = new Thread( () => { secondWriteSemaphore.Wait(); secondWriteReleaser = l.WriteLock(); }); secondWriteThread.Priority = ThreadPriority.Highest; secondWriteThread.Start(); await(AssertEqualValueAsync(() => secondWriteThread.ThreadState == ThreadState.WaitSleepJoin, true)); var secondReadThreads = new Thread[20]; var secondReadReleasers = new AsyncReaderWriterLock.Releaser[secondReadThreads.Length]; var secondReadSemaphore = new SemaphoreSlim(0); for (var j = 0; j < secondReadReleasers.Length; j++) { var index = j; var thread = new Thread( () => { secondReadSemaphore.Wait(); secondReadReleasers[index] = l.ReadLock(); }); thread.Priority = ThreadPriority.Highest; secondReadThreads[j] = thread; thread.Start(); } await(AssertEqualValueAsync(() => secondReadThreads.All(o => o.ThreadState == ThreadState.WaitSleepJoin), true)); var firstReadReleaserTasks = new Task[30]; var firstReadStopSemaphore = new SemaphoreSlim(0); for (var j = 0; j < firstReadReleaserTasks.Length; j++) { firstReadReleaserTasks[j] = Task.Run(async() => { var releaser = await(l.ReadLockAsync()); await(firstReadStopSemaphore.WaitAsync()); releaser.Dispose(); }); } await(AssertEqualValueAsync(() => l.ReadersWaiting, firstReadReleaserTasks.Length, waitDelay: 60000)); writeReleaser.Dispose(); secondWriteSemaphore.Release(); secondReadSemaphore.Release(secondReadThreads.Length); await(Task.Delay(1000)); firstReadStopSemaphore.Release(firstReadReleaserTasks.Length); await(AssertEqualValueAsync(() => firstReadReleaserTasks.All(o => o.IsCompleted), true)); Assert.That(l.ReadersWaiting, Is.EqualTo(secondReadThreads.Length)); Assert.That(l.CurrentReaders, Is.EqualTo(0)); await(AssertEqualValueAsync(() => secondWriteThread.IsAlive, false)); await(AssertEqualValueAsync(() => secondReadThreads.All(o => o.IsAlive), true)); secondWriteReleaser.Dispose(); await(AssertEqualValueAsync(() => secondReadThreads.All(o => !o.IsAlive), true)); Assert.That(l.ReadersWaiting, Is.EqualTo(0)); Assert.That(l.CurrentReaders, Is.EqualTo(secondReadThreads.Length)); foreach (var secondReadReleaser in secondReadReleasers) { secondReadReleaser.Dispose(); } Assert.That(l.ReadersWaiting, Is.EqualTo(0)); Assert.That(l.CurrentReaders, Is.EqualTo(0)); } }
public async Task <PeerAppDataResult> SetPeerAppDataAsync(string peerId, string connectionId, SetPeerAppDataRequest setPeerAppDataRequest) { using (await _peersLock.ReadLockAsync()) { if (!_peers.TryGetValue(peerId, out var peer)) { throw new Exception($"SetPeerAppDataAsync() | Peer:{peerId} is not exists."); } CheckConnection(peer, connectionId); return(await peer.SetPeerAppDataAsync(setPeerAppDataRequest)); } }