-
Notifications
You must be signed in to change notification settings - Fork 17.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
net: File method of {TCP,UDP,IP,Unix}Conn and {TCP,Unix}Listener should leave the socket in nonblocking mode #24942
Comments
Probably irrelevant detail: the reason I am calling File() on the listener at all is so that I can add it to (exec.Command).ExtraFiles to pass it to a subprocess. Definitely no desire to change the socket behavior in so doing. |
@ianlancetaylor The change is trivial but do we care about the behavior change? Unlike what was done with os.File, we cannot easily enhance an existing method. |
The package net methods return a |
The only nuance I am aware is that Deadline calls now work. |
Shall this also apply to IPConn and TCPConn or just TCPListener? Seems weird to only have one behave differently, plus its easier to affect all 3. |
I assume it should affect all three. |
Change https://golang.org/cl/108297 mentions this issue: |
I would guess that fd's were set to nonblocking to begin with (a144e3e) was for a roundabout way of deregistering from epoll (the logic is a bit to follow for the repo at that time). dup would've been problematic because a Close did not deregister from epoll, meaning a registered fd would never be unregistered. netFD's now unconditionally fall into EPOLL_CTL_DEL on close, so this is no longer an issue. Removing |
Didn't realize this issue had closed (was looking into commits for too long with this page open) -- I'll move portions of that last comment to the relevant open issues. |
Note that this might be a surprise to people who rely on the go1compt promise. What happens when people having two executables built by go1.10 or below and go1.11 or above, and the executables need to share a single underlying socket? The go1.10 executable assumes that the passed cloned descriptor points to the blocking mode socket but the go1.11 executable passes the cloned descriptor pointing to the non-blocking mode socket. Of course, there's no problem when people use net.File{Conn,PacketConn,Listener} functions in the go1.10 executables instead of functions from the syscall and x/net/unix packages. Is it safe to bet/assume on that? (not sure, probably it's okay because functions and primitives provided by syscall and x/net/unix packages are just for people who understand what's the right thing and what they are doing) |
@mikioh I think that the cases you are describing are fairly unlikely. I agree that there are cases that can break. Let's see what happens. If people find bugs, we can roll back. |
What version of Go are you using (
go version
)?1.10.1
Does this issue reproduce with the latest release?
Yes.
What operating system and processor architecture are you using (
go env
)?linux/amd64 and darwin/amd64
What did you do?
What did you expect to see?
Server graceful shutdown.
What did you see instead?
Shutdown() returned immediately but Serve() never returned.
Diagnosis
The call to File() on the listener puts the socket in blocking mode. As a result, when the listener is closed, the Accept() called by Serve() does not return. Note that, if the call to File() is moved so that it occurs after the call to Accept(), the problem does not occur.
Response from [email protected] on golang-nuts, April 18, 2018:
The text was updated successfully, but these errors were encountered: