/// <summary> /// Attempts to acquire the specified resources /// </summary> /// <param name="resources">the resources to acquire</param> /// <param name="limitingResourceIndex">the first encountered semaphore limiting resource acquisition if any</param> /// <param name="force">true to force acquisition of the resources even acquisition would exceed limits for the semaphores</param> /// <returns>true if the resources where successfully acquired. False, otherwise.</returns> public bool TryAcquireResources(ItemResources resources, out int?limitingResourceIndex, bool force = false) { if (!resources.IsValid || resources.SemaphoreIncrements.Length == 0) { limitingResourceIndex = null; return(true); } lock (SyncLock) { if (!HasAvailableResourcesCore(resources, out limitingResourceIndex, force)) { return(false); } for (int i = 0; i < resources.SemaphoreIncrements.Length; i++) { int usageCount = resources.SemaphoreIncrements[i]; if (usageCount == 0) { continue; } m_semaphoreUsages[i] += usageCount; Contract.Assume(force || m_semaphoreUsages[i] <= SemaphoreLimits[i]); } } limitingResourceIndex = null; return(true); }
private bool HasAvailableResourcesCore(ItemResources resources, out int?limitingResourceIndex, bool force = false) { Contract.Assume( resources.SemaphoreIncrements.Length <= SemaphoreLimits.Count, "ItemResources uses unknown semaphore indices."); Array.Resize(ref m_semaphoreUsages, SemaphoreLimits.Count); if (!force) { for (int i = 0; i < resources.SemaphoreIncrements.Length; i++) { int usageCount = resources.SemaphoreIncrements[i]; if (usageCount == 0) { continue; } if ((m_semaphoreUsages[i] + usageCount) > SemaphoreLimits[i]) { limitingResourceIndex = i; return(false); } } } limitingResourceIndex = null; return(true); }
/// <summary> /// Gets whether the semaphore set currently can acquire the given resources /// </summary> /// <param name="resources">the resources to acquire</param> /// <returns>true if the resources where available. False, otherwise.</returns> public bool HasAvailableResources(ItemResources resources) { if (!resources.IsValid || resources.SemaphoreIncrements.Length == 0) { return(true); } lock (SyncLock) { return(HasAvailableResourcesCore(resources, out int?limitingResourceIndex)); } }
/// <summary> /// Releases the resources /// </summary> public void ReleaseResources(ItemResources resources) { if (!resources.IsValid || resources.SemaphoreIncrements.Length == 0) { return; } lock (SyncLock) { Array.Resize(ref m_semaphoreUsages, SemaphoreLimits.Count); for (int i = 0; i < resources.SemaphoreIncrements.Length; i++) { int usageCount = resources.SemaphoreIncrements[i]; m_semaphoreUsages[i] -= usageCount; Contract.Assume(m_semaphoreUsages[i] >= 0); } } }
/// <summary> /// Attempts to acquire the specified resources /// </summary> /// <param name="resources">the resources to acquire</param> /// <param name="force">true to force acquisition of the resources even acquisition would exceed limits for the semaphores</param> /// <returns>true if the resources where successfully acquired. False, otherwise.</returns> public bool TryAcquireResources(ItemResources resources, bool force = false) { int?limitingResourceIndex; return(TryAcquireResources(resources, out limitingResourceIndex, force)); }
/// <summary> /// Creates an instance /// </summary> public ItemSemaphoreQueuedEventArgs(bool queued, TItem item, ItemResources itemResources) { Queued = queued; Item = item; ItemResources = itemResources; }