public T GetObject() { KeyValuePair <long, T>?firstAllocator = null; if (Interlocked.Increment(ref checkCompleted) >= CHECK_COMPLETED_INTERVAL) { checkCompleted = 0; // this check is slow, so only do it occassionally // this may cause more objects to get created, but that is fine // more things will come safely off the queue when this updates GraphicsDevice.GetCompletedValue(); } bool lockTaken = false; try { spinLock.Enter(ref lockTaken); if (liveObjects.Count > 0) { firstAllocator = liveObjects.Peek(); if (firstAllocator.Value.Key < GraphicsDevice.lastCompletedFence) { liveObjects.Dequeue(); } else { firstAllocator = null; } } } finally { if (lockTaken) { spinLock.Exit(true); } } if (firstAllocator.HasValue) { ResetObject(firstAllocator.Value.Value); return(firstAllocator.Value.Value); } return(CreateObject()); }
public T GetObject() { lock (liveObjects) { // Check if first allocator is ready for reuse if (liveObjects.Count > 0) { var firstAllocator = liveObjects.Peek(); if (firstAllocator.Key <= GraphicsDevice.GetCompletedValue()) { liveObjects.Dequeue(); ResetObject(firstAllocator.Value); return(firstAllocator.Value); } } } return(CreateObject()); }