                 task.fail(error: EventLoopError.shutdown)
             }
         }
+        var nextReadyTask: ScheduledTask? = nil
         while lifecycleState != .closed {
             // Block until there are events to handle or the selector was woken up
             /* for macOS: in case any calls we make to Foundation put objects into an autoreleasepool */
             try withAutoReleasePool {
 
-                try selector.whenReady(strategy: currentSelectorStrategy()) { ev in
+                try selector.whenReady(strategy: currentSelectorStrategy(nextReadyTask: nextReadyTask)) { ev in
                     switch ev.registration {
                     case .serverSocketChannel(let chan, _):
                         self.handleEvent(ev.io, channel: chan)

                // TODO: Better locking
                tasksLock.lock()
                if scheduledTasks.isEmpty {
                    tasksLock.unlock()
                    break
                }

                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() {
                    if task.readyIn(now) <= .nanoseconds(0) {
                        _ = scheduledTasks.pop()
                        tasksCopy.append(task.task)
                    } else {
                        nextReadyTask = task
                        break
                    }
                }

                tasksLock.unlock()

                // all pending tasks are set to occur in the future, so we can stop looping.
                if tasksCopy.isEmpty {
                    break
                }

