-
Notifications
You must be signed in to change notification settings - Fork 656
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Not retry calling close(...) when EINTR is reported. #217
Conversation
71b8ffa
to
43fc0e0
Compare
Thanks to @vlm for reporting. |
@swift-nio-bot test this please |
Sources/NIO/System.swift
Outdated
/* Sorry, we really try hard to not use underscored attributes. In this case however we seem to break the inlining threshold which makes a system call take twice the time, ie. we need this exception. */ | ||
@inline(__always) | ||
internal func wrapSyscall<T: FixedWidthInteger>(where function: StaticString = #function, _ body: () throws -> T) throws -> T { | ||
internal func wrapSyscall<T: FixedWidthInteger>(where function: StaticString = #function, continueOnErrno: (CInt) -> Bool = continueOnEINTR, _ body: () throws -> T) throws -> T { |
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.
Should we just make this a separate function rather than use the closure?
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.
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 a bit reluctant to combine @inline(__always)
with this closure, that's all.
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.
ok let me just add an extra method then... Its easy enough to do :)
Motivation: If close(...) reports EINTR there is nothing sane we can do so it makes no sense to even report it. See also: apple/swift-nio#217 Modifications: Just ignore EINTR when calling close(...) Result: Less noise in the logs.
43fc0e0
to
c41f8ac
Compare
Sources/NIO/System.swift
Outdated
throw IOError(errnoCode: err, function: function) | ||
} | ||
return res | ||
} |
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.
In this case don't we just want to suppress the return of EINTR altogether? I don't think we need to throw at all.
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.
works for me as well...
c41f8ac
to
f5a8b85
Compare
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.
looks good to me. Are we confident that close
just worked if EINTR
was returned?
@weissi check the links that are included in the comments... Basically there is really nothing we can do about it and the "safest" bet is to assume it worked. |
@swift-nio-bot test this please |
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.
This is fine by me. Sadly it's almost impossible to trigger for testing purposes: time to stub out the kernel? 😉
@swift-nio-bot test this please |
Motivation: Usually we retry the syscall when EINTR is reported. This is not safe in the case of close(...) as the file descriptor may already be closed. The problem arise if this was the case and we retry it and the file descriptor is already reused again. In this case we would close a wrong file descriptor. See: - https://bugs.chromium.org/p/chromium/issues/detail?id=269623 - https://lwn.net/Articles/576478/ Modifications: Ignore EINTR on close(...) and just assume the FD was closed. Result: Not possible to close the wrong file descriptor when close(...) reports EINTR.
42fd4b0
to
ad81425
Compare
@Lukasa it should actually be quite possible to trigger it:
I think this should be enough to reliably observe EINTR. If not, the whole thing should be tried with an NFS instead of sockets, but that complicates stuff greatly. |
No, turned out under Linux it is pretty impossible to get it this way. Take it back. |
Motivation: If close(...) reports EINTR there is nothing sane we can do so it makes no sense to even report it. See also: apple/swift-nio#217 Modifications: Just ignore EINTR when calling close(...) Result: Less noise in the logs.
Motivation:
Usually we retry the syscall when EINTR is reported. This is not safe in the case of close(...) as the file descriptor may already be closed. The problem arise if this was the case and we retry it and the file descriptor is already reused again. In this case we would close a wrong file descriptor.
See:
Modifications:
Ignore EINTR on close(...) and just assume the FD was closed.
Result:
Not possible to close the wrong file descriptor when close(...) reports EINTR.