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

Making evented I/O work on macOS #5286

Closed
wants to merge 3 commits into from
Closed

Making evented I/O work on macOS #5286

wants to merge 3 commits into from

Conversation

kristoff-it
Copy link
Member

@kristoff-it kristoff-it commented May 7, 2020

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 .

Copy link
Member

@andrewrk andrewrk left a 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 {
Copy link
Member

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)

Suggested change
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) {
Copy link
Member

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 {
Copy link
Member

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) {
Copy link
Member

Choose a reason for hiding this comment

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

Related: #1908

@andrewrk andrewrk closed this in 3aa259d May 7, 2020
@kristoff-it
Copy link
Member Author

For future reference, this is the moment when we made the code work https://clips.twitch.tv/AssiduousMotionlessScorpionDansGame

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants