                         task()
                     }
                 }
+                // Drop everything (but keep the capacity) so we can fill it again on the next iteration.
+                tasksCopy.removeAll(keepingCapacity: true)
             }
         }
 

    private let selector: NIO.Selector<NIORegistration>
    private let thread: Thread
    private var scheduledTasks = PriorityQueue<ScheduledTask>(ascending: true)
    private let tasksLock = Lock()
    private var lifecycleState: EventLoopLifecycleState = .open


                    tasksLock.unlock()
                    break
                }

                // We only fetch the time one time as this may be expensive and is generally good enough as if we miss anything we will just do a non-blocking select again anyway.
                let now = DispatchTime.now()

                // Make a copy of the tasks so we can execute these while not holding the lock anymore
                while tasksCopy.count < tasksCopy.capacity, let task = scheduledTasks.peek(), task.readyIn(now) <= .nanoseconds(0) {
                    tasksCopy.append(task.task)

                    _ = scheduledTasks.pop()
