Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/crystal/event_loop.cr
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,13 @@ abstract class Crystal::EventLoop
abstract def run(queue : Fiber::List*, blocking : Bool) : Nil
{% end %}

# Blocks the current scheduler until all the pending events have completed.
# Must yield every runnable fiber.
#
# Optional.
def drain(& : Fiber ->) : Nil
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thought: Since the implementation is optional and we really only need it for a single implementation, maybe we shouldn't add it to the generic interface? It seems silly to have this method on all event loop interfaces but it doesn't do anything.
As an alternative, we could implement it only for EventLoop::IOUring and check with @event_loop.responds_to?(:drain).

end

# Tells a blocking run loop to no longer wait for events to activate. It may
# for example enqueue a NOOP event with an immediate (or past) timeout. Having
# activated an event, the loop shall return, allowing the blocked thread to
Expand Down
3 changes: 3 additions & 0 deletions src/fiber/execution_context/parallel/scheduler.cr
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,10 @@ module Fiber::ExecutionContext
loop do
if @shutdown
spin_stop

# drain everything into the global queue
@runnables.drain
@event_loop.drain { |fiber| @global_queue.push(fiber) }

# we may have been the last running scheduler, waiting on the event
# loop while there are pending events for example; let's resume a
Expand Down