/// <summary> /// Acquires a resource according to the specified resource request, either blocking until successful, or /// returning <null> if the resource is not immediately available. /// </summary> /// <param name="resourceRequest">The IResourceRequest that specifies the criteria by which to select the resource.</param> /// <param name="blockAwaitingAcquisition">If true, request will suspend until granted. If false, will return false if unable to fulfill.</param> /// <returns>True if granted, false if not granted.</returns> public bool Acquire(IResourceRequest resourceRequest, bool blockAwaitingAcquisition) { if (blockAwaitingAcquisition) { IDetachableEventController dec = Model.Executive.CurrentEventController; if (dec == null) { throw new ApplicationException("Someone tried to call Acquire(..., true) while not in a detachable event. This is not allowed."); } dec.SetAbortHandler(resourceRequest.AbortHandler); resourceRequest.ResourceRequestAborting += m_onResourceRequestAborting; while (true) { if (Acquire(resourceRequest)) { break; } m_waiters.Add(dec); dec.Suspend(); dec.ClearAbortHandler(); } return(true); } else { return(Acquire(resourceRequest)); } }
/// <summary> /// Acquires the resource and quantity specifed by the resource request, blocking /// until it can return successfully. /// </summary> /// <param name="request">The resource request that describes the desired resource and quantity.</param> /// <returns>Always true.</returns> protected bool AcquireWithWait(IResourceRequest request) { IDetachableEventController dec = Model.Executive.CurrentEventController; if (dec == null) { throw new ApplicationException("Someone tried to call AcquireWithWait() while not in a detachable event. This is not allowed."); } dec.SetAbortHandler(request.AbortHandler); request.ResourceRequestAborting += m_onResourceRequestAborting; while (!Acquire(request, false)) { m_waiters.Add(request, dec); dec.Suspend(); dec.ClearAbortHandler(); } if (request.ResourceObtained != null) { ResourceAcquired?.Invoke(request, request.ResourceObtained); return(true); } else { return(false); } }
private void LogSynchronization(object sortKey, IDetachableEventController idec, SynchChannel sc) { if (m_waiters.ContainsValue(idec)) { throw new ApplicationException("Synchronize(...) called on a SynchChannel that is already waiting."); } if (!m_synchChannels.Contains(sc)) { throw new ApplicationException("SynchChannel applied to a synchronizer that did not own it - serious error."); } if ((m_waiters.Count + 1) == m_synchChannels.Count) { m_exec.RequestEvent(new ExecEventReceiver(LaunchAll), m_exec.Now, m_exec.CurrentPriorityLevel, null); } m_waiters.Add(sortKey, idec); idec.SetAbortHandler(new DetachableEventAbortHandler(idec_AbortionEvent)); idec.Suspend(); idec.ClearAbortHandler(); }