@@ -290,26 +290,40 @@ auto io_scheduler::process_events_execute(std::chrono::milliseconds timeout) ->
290290
291291auto io_scheduler::process_scheduled_execute_inline () -> void
292292{
293- std::vector<std::coroutine_handle<>> tasks{};
293+ // Clear the schedule eventfd if this is a scheduled task.
294+ int control = 0 ;
295+ ::read (m_schedule_fd[1 ], reinterpret_cast <void *>(&control), sizeof(control));
296+
297+ // Clear the in memory flag to reduce eventfd_* calls on scheduling.
298+ m_schedule_fd_triggered.exchange (false , std::memory_order::release);
299+
300+ constexpr std::size_t MAX{32 };
301+ std::size_t processed{0 };
302+ while (true )
294303 {
295- // Acquire the entire list, and then reset it.
296- std::scoped_lock lk{m_scheduled_tasks_mutex};
297- tasks.swap (m_scheduled_tasks);
304+ std::array<std::coroutine_handle<>, MAX> tasks{nullptr };
305+ if (!m_scheduled_tasks.try_dequeue_bulk (tasks.data (), MAX))
306+ {
307+ break ;;
308+ }
298309
299- // Clear the schedule eventfd if this is a scheduled task.
300- int control = 0 ;
301- ::read (m_schedule_fd[1 ], reinterpret_cast <void *>(&control), sizeof(control));
310+ for (std::size_t i = 0 ; i < MAX; ++i)
311+ {
312+ auto & handle = tasks[i];
313+ if (handle == nullptr )
314+ {
315+ break ;
316+ }
302317
303- // Clear the in memory flag to reduce eventfd_* calls on scheduling.
304- m_schedule_fd_triggered.exchange (false , std::memory_order::release);
318+ handle.resume ();
319+ ++processed;
320+ }
305321 }
306322
307- // This set of handles can be safely resumed now since they do not have a corresponding timeout event.
308- for (auto & task : tasks)
323+ if (processed > 0 )
309324 {
310- task. resume ( );
325+ m_size. fetch_sub (processed, std::memory_order::release );
311326 }
312- m_size.fetch_sub (tasks.size (), std::memory_order::release);
313327}
314328
315329auto io_scheduler::process_event_execute (detail::poll_info* pi, poll_status status) -> void
0 commit comments