/// <nodoc /> public void UnsafeClear() { // Order is important here, inverse order could cause deadlock. using (_flushMutex.AcquireSemaphore()) using (_exchangeLock.AcquireWriteLock()) { if (_cache.Count != 0) { // Nothing guarantees that some number of updates couldn't have happened in between the last flush // and this reset, because acquisition of the write lock happens after the flush lock. The only way // to deal with this situation is to force a flush before this assignment and after locks have been // acquired. However, this isn't required by our code right now; although it is a simple change. _cache = new ConcurrentBigMap <ShortHash, ContentLocationEntry>(); } } }
public void Dispose() { using (m_queryJobDataLock.AcquireWriteLock()) { // Prevent further data queries m_disposeStarted = true; } if (m_processStarted) { InternalKill(); m_resultTaskCompletionSource.Task.Wait(); } m_detouredProcess?.Dispose(); m_detouredProcess = null; m_output?.Dispose(); m_output = null; m_error?.Dispose(); m_error = null; m_reports = null; m_fileAccessManifestStreamWrapper.Dispose(); }
protected void TogglePauseChooseWorkerQueue(bool pause, RunnablePip blockedPip = null) { Contract.Requires(pause == (blockedPip != null), "Must specify blocked pip if and only if pausing the choose worker queue"); if (pause) { using (m_chooseWorkerTogglePauseLock.AcquireWriteLock()) { // Compare with the captured sequence number before the pip re-entered the queue // to avoid race conditions where pip cannot acquire worker resources become available then queue is paused // potentially indefinitely (not likely but theoretically possilbe) if (Volatile.Read(ref WorkerEnableSequenceNumber) == blockedPip.ChooseWorkerSequenceNumber) { SetQueueMaxParallelDegree(0); } } } else { using (m_chooseWorkerTogglePauseLock.AcquireReadLock()) { // Update the sequence number. This essentially is called for every increase in resources // and successful acquisition of workers to track changes in resource state that invalidate // decision to pause choose worker queue. Interlocked.Increment(ref WorkerEnableSequenceNumber); // Unpause the queue SetQueueMaxParallelDegree(MaxParallelDegree); } } }
/// <summary> /// Tries to kill the process and all child processes. /// </summary> /// <remarks> /// It's okay to call this method at any time; however, before process start and after process termination or disposing of /// this instance, it does nothing. /// </remarks> public void Kill(int exitCode) { // Notify the injected that the process is being killed m_processInjector?.OnKilled(); var processHandle = m_processHandle; if (processHandle != null && !processHandle.IsInvalid) { // Ignore result, as there is a race with regular process termination that we cannot do anything about. m_killed = true; // No job object means that we are on an old OS; let's just terminate this process (we can't reliably terminate all child processes) Analysis.IgnoreResult(Native.Processes.ProcessUtilities.TerminateProcess(processHandle, exitCode)); } using (m_queryJobDataLock.AcquireWriteLock()) { JobObject jobObject = m_job; if (jobObject != null) { // Ignore result, as there is a race with regular shutdown. m_killed = true; Analysis.IgnoreResult(jobObject.Terminate(exitCode)); } } }
/// <summary> /// Add a mapping from <paramref name="machineId"/> to <paramref name="machineLocation"/>. /// </summary> public void AddMachine(MachineId machineId, MachineLocation machineLocation) { using (_lock.AcquireWriteLock()) { while (machineId.Index >= _locationByIdMap.Length) { Array.Resize(ref _locationByIdMap, _locationByIdMap.Length * 2); } _locationByIdMap[machineId.Index] = machineLocation; } _idByLocationMap[machineLocation] = machineId; }
private Result <ClusterStateInternal> Mutate(Func <ClusterStateInternal, Result <ClusterStateInternal> > mutation) { using var token = _lock.AcquireWriteLock(); var newClusterState = mutation(ClusterStateInternal.Value !); if (!newClusterState.Succeeded) { return(newClusterState); } ClusterStateInternal = newClusterState; return(ClusterStateInternal); }
/// <summary> /// Finishes up/cleans remaining RocksDB tasks and flushes DB to disk. /// </summary> public void Dispose() { using (m_rwl.AcquireWriteLock()) { if (!m_disposed) { m_disposed = true; if (m_invalidateStoreOnDispose) { InvalidateStore(); } ((RocksDbStore)m_store).Dispose(); } } }
/// <summary> /// Finishes up/cleans remaining RocksDB tasks and flushes DB to disk. /// </summary> public void Dispose() { using (m_rwl.AcquireWriteLock()) { if (!m_disposed) { m_disposed = true; if (m_invalidateStoreOnDispose) { InvalidateStore(); } if (m_store is IDisposable disposableStore) { disposableStore.Dispose(); } } } }