-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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
Making evented I/O work on macOS #5286
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm happy to merge this in its current state
@@ -503,7 +503,7 @@ pub const Loop = struct { | |||
} | |||
} | |||
|
|||
pub async fn bsdWaitKev(self: *Loop, ident: usize, filter: i16, fflags: u32) void { | |||
pub async fn bsdWaitKev(self: *Loop, ident: usize, filter: i16, flags: u16) void { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No async needed here (this is leftover from before the async/await rewrite)
pub async fn bsdWaitKev(self: *Loop, ident: usize, filter: i16, flags: u16) void { | |
pub fn bsdWaitKev(self: *Loop, ident: usize, filter: i16, flags: u16) void { |
|
||
defer { | ||
// If the kevent was set to be ONESHOT, it doesn't need to be deleted manually. | ||
if (flags & os.EV_ONESHOT != 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we maybe want to assert that flags always contains EV_ONESHOT
and document the requirement in doc comments? It's true in all the callsites of this function.
} | ||
} | ||
|
||
/// resume_node must live longer than the anyframe that it holds a reference to. | ||
pub fn bsdAddKev(self: *Loop, resume_node: *ResumeNode.Basic, ident: usize, filter: i16, fflags: u32) !void { | ||
pub fn bsdAddKev(self: *Loop, resume_node: *ResumeNode.Basic, ident: usize, filter: i16, flags: u16) !void { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow nice catch on the filter flags, I can't believe I was passing EV_ONESHOT to the wrong parameter 😰
.dragonfly, | ||
=> self.fs_thread.wait(), | ||
else => {}, | ||
if (!builtin.single_threaded) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Related: #1908
For future reference, this is the moment when we made the code work https://clips.twitch.tv/AssiduousMotionlessScorpionDansGame |
This PR contains two reasonably solid fixes and one tentative fix that should be discussed first.
Fix 1
Simple fix on a crash caused by a missing
builtin.single_threaded
check.Fix 2
Fixes a race condition crash based on
EV_ONESHOT
being erroneusly passed as a filter_flag (thanks JX7P from IRC, we were running in circles :D)Fix 3
As of now, when calling
connect
we were checking for the socket to be either readable or writable. In kqueue this doesn't seem to be possible, which exposes the problem that if the other host is not sending anything, the connection never becomes readable. This makes me question whether we really need to check for both conditions before proceeding. For example this deadlocks my Redis client because it's the client that's supposed to speak first.Related issue: #5278.
Thanks @haze @FireFox317 @SuperAuguste, chaplchapl and @alexnask .