private IEnumerator SucceedGetMaterialDataRequests(string materialDataKey, MaterialData materialData) { CheckIfMainThread(); // Check to see if any other requests were waiting on this model LinkedList <LoadCubeRequest> dependentRequests; while (!Monitor.TryEnter(_dependentCubes)) { yield return(null); } if (_dependentCubes.TryGetValue(materialDataKey, out dependentRequests)) { _dependentCubes.Remove(materialDataKey); } Monitor.Exit(_dependentCubes); while (!Monitor.TryEnter(MaterialDataCache)) { yield return(null); } // If any were send them to their next stage if (dependentRequests != null) { foreach (var request in dependentRequests) { request.MaterialData = materialData; MaterialDataCache.AddRef(request.MaterialData.DiffuseTexPath); MoveRequestForward(request); } } // Now that added references for the dependent requests. We can release the interim reference MaterialDataCache.Release(materialData.DiffuseTexPath); Monitor.Exit(MaterialDataCache); }
// Helper for locking a queue, pulling off requests and invoking a handler function for them private void ProcessQueue(Queue <LoadCubeRequest> queue, Func <LoadCubeRequest, IEnumerator> requestProcessFunc, int limit) { var noLimit = limit == 0; if (Monitor.TryEnter(queue)) { try { while (queue.Count > 0 && (noLimit || (limit-- > 0))) { var request = queue.Dequeue(); if (!request.Cancelled) { StartCoroutine(requestProcessFunc(request)); } else { lock (MaterialDataCache) { if (request.MaterialData != null && request.MaterialData.DiffuseTex != null) { MaterialDataCache.Release(request.MaterialData.DiffuseTex.name); } } CancelledRequests++; } } } finally { Monitor.Exit(queue); } } }