             action();
             existingStorage.context = oldContext;
         } else {
-            // Current queue doesn't have any context stored, move on to the default queue
+            // Current queue doesn't have any context stored, move on to a queue
             // Could also call createQueueWithNewContext() here, but that is slow
-            _defaultContextQueue.sync(execute: {
+            let queue = BindingQueuePool.retrieveContextQueue();
+            defer { BindingQueuePool.returnContextQueue(queue); }
+            
+            queue.sync(execute: {
                 let existingStorage = BindingContext.currentStorage!;
                 
                 // Generate a new context


import Foundation

private let _contextSpecificName = DispatchSpecificKey<QueueBindingContext>();

///
/// Binding context queue to use if the current queue is not already a binding queue
///
/// This is not used for the purposes of serialization but rather because creating new queues is bad for performance.
/// This can have the unexpected consequence that all computed values are computed on the same queue.
///
private let _defaultContextQueue = BindingContext.createQueueWithNewContext();

///
/// Stores the binding context for the current queue

        queue.setSpecific(key: _contextSpecificName, value: storage);
        
        return queue;
    }
    
    ///
    /// Retrieves a context queue, or waits for one to become available
    ///
    static func retrieveContextQueue() -> DispatchQueue {
        // Acquire the semaphore
        _queueSemaphore.wait();
        defer { _queueSemaphore.signal(); }
        
        // If there are no queues available, then wait for someone to signal the wait semaphore
        while _contextQueues.count <= 0 {
            // Release the queue semaphore so that queues can be returned
            _queueSemaphore.signal();
            
            // Wait for the wait semaphore to be signaled (indicates a queue was returned to the pool)
            _queueWaitSemaphore.wait();
            _queueWaitSemaphore.signal();
            
            // Re-acquire the queue semaphore so we can check for queues
            _queueSemaphore.wait();
        }
        
        // If we got the semaphore, there is always at least one queue available in the list
        let queue = _contextQueues.popLast()!;
        
        // If we just got the last queue, then acquire the wait semaphore so we can block anything waiting for a queue
        if _contextQueues.count == 0 {
            _queueWaitSemaphore.wait();
        }
        
        // Release the semaphore and return the result
        return queue;
    }
    
    ///
    /// Returns a context queue to the pool
    ///
    static func returnContextQueue(_ queue: DispatchQueue) {
        // Acquire the semaphore
        _queueSemaphore.wait();
        defer { _queueSemaphore.signal(); }
        
        // If this is the first queue back in the pool, then wake any threads waiting for more queues
        if _contextQueues.count == 0 {
            _queueWaitSemaphore.signal();
        }
        
        // Return queue to the pool
        _contextQueues.append(queue);
    }
}

///
/// The binding context is used to keep track of what bindings are being accessed
///
public class BindingContext {
    ///
    /// The dependencies that have been created in this context
    ///
    fileprivate var _dependencies = CombinedChangeable();
    
    ///
    /// Dependencies that we expected to see
    ///
    fileprivate var _expectedDependencies: CombinedChangeable?;
    
    ///
    /// Call BindingContext.current to get the binding context for the current queue
    ///
    fileprivate init() {
    }
    
    fileprivate static var currentStorage: QueueBindingContext? {
        @inline(__always)
        get {
            // Get the context pointer from the queue
            return DispatchQueue.getSpecific(key: _contextSpecificName);
        }
    }
    
    ///
    /// Retrieves the binding context for the current queue (or nil if there isn't one)
    ///
    public static var current: BindingContext? {
        get {
            return currentStorage?.context;
        }
    }
    
    ///
