Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EventLoop::IOCP: requirements #35

Closed
ysbaddaden opened this issue Nov 25, 2024 · 3 comments
Closed

EventLoop::IOCP: requirements #35

ysbaddaden opened this issue Nov 25, 2024 · 3 comments
Assignees
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@ysbaddaden
Copy link
Owner

ysbaddaden commented Nov 25, 2024

Here is the list of requirements to make the Windows IOCP event loop fully compatible with EC:

  • EV::IOCP SHOULD yield runnable fibers internally, so we can monkey patch EV::IOCP#run(EC::Queue*, Bool) in src/core_ext/event_loop;

  • EV::IOCP MUST wait for completion even when there are no queued events (aka timers) because there might be async operations (unaccounted);

  • EV::IOCP SHOULD wait forever when blocking (same as EV::Polling) for the previous fix to behave correctly;

  • EV::IOCP SHOULD use a distinct timer because another thread MAY enqueue a timer expiring sooner at any time in parallel (bonus: higher precision?);

  • EV::IOCP MUST refresh next_event after System::IOCP.wait_for_completion returned: another thread MAY have enqueued a timer expiring sooner;

  • Accessing @queue must be protected by a Thread::Mutex!

Bonuses:

  • System::IOCP SHOULD remove more than 1 completed operation (Go removes 64, while we remove 128 in EV::Polling).

  • EV::IOCP SHOULD loop when we fail to dequeue the next event (dead fiber) since there might be another expired timer or SHOULD dequeue all ready timers?

  • Interrupt GetQueuedCompletionStatusEx with PostQueuedCompletionStatus which seems a more natural way to report an event, instead of QueueUserAPC to the thread to get the wait.

  • Consider Crystal::PointerPairingHeap for storing timers. The complexity is that EV::IOCP::Event is a class while the heap assumes a pointer to structs.

@ysbaddaden ysbaddaden self-assigned this Nov 25, 2024
@ysbaddaden
Copy link
Owner Author

Related: crystal-lang/crystal#14949

@ysbaddaden ysbaddaden added enhancement New feature or request help wanted Extra attention is needed labels Nov 25, 2024
@ysbaddaden
Copy link
Owner Author

ysbaddaden commented Nov 26, 2024

Win32 functions for IOCP compatible timers:

  1. CreateWaitableTimerExW (create timer) with CREATE_WAITABLE_TIMER_HIGH_RESOLUTION flag;
  2. NtCreateWaitCompletionPacket (create packet for timer);
  3. NtAssociateWaitCompletionPacket (arm timer);
  4. NtCancelWaitCompletionPacket (disarm timer).

@ysbaddaden
Copy link
Owner Author

All implemented in crystal-lang/crystal#15238. It works there, but it's still untested with execution contexts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

1 participant