Skip to content

Commit 4153495

Browse files
os: calling Fd disables the SetDeadline methods
The full truth seems too complicated to write in this method's doc, so I'm going with a simple half truth. The full truth is that Fd returns the descriptor in blocking mode, because that is historically how it worked, and existing programs would be surprised if the descriptor is suddenly non-blocking. On Unix systems whether a file is non-blocking or not is a property of the underlying file description, not of a particular file descriptor, so changing the returned descriptor to blocking mode also changes the existing File to blocking mode. Blocking mode works fine, althoug I/O operations now take up a thread. SetDeadline and friends rely on the runtime poller, and the runtime poller only works if the descriptor is non-blocking. So it's correct that calling Fd disables SetDeadline. The other half of the truth is that if the program is willing to work with a non-blocking descriptor, it could call syscall.SetNonblock(descriptor, true) to change the descriptor, and the original File, to non-blocking mode. At that point SetDeadline would start working again. I tried to write that in a way that is short and comprehensible but failed. Since deadlines mostly work on pipes, and there isn't much reason to call Fd on a pipe, and few people use SetDeadline, I decided to punt. Fixes #22934 Change-Id: I2e49e036f0bcf71f5365193831696f9e4120527c Reviewed-on: https://go-review.googlesource.com/81636 Reviewed-by: Brad Fitzpatrick <[email protected]>
1 parent bfa7a55 commit 4153495

File tree

3 files changed

+3
-0
lines changed

3 files changed

+3
-0
lines changed

src/os/file_plan9.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ type file struct {
2929

3030
// Fd returns the integer Plan 9 file descriptor referencing the open file.
3131
// The file descriptor is valid only until f.Close is called or f is garbage collected.
32+
// On Unix systems this will cause the SetDeadline methods to stop working.
3233
func (f *File) Fd() uintptr {
3334
if f == nil {
3435
return ^(uintptr(0))

src/os/file_unix.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ type file struct {
5454

5555
// Fd returns the integer Unix file descriptor referencing the open file.
5656
// The file descriptor is valid only until f.Close is called or f is garbage collected.
57+
// On Unix systems this will cause the SetDeadline methods to stop working.
5758
func (f *File) Fd() uintptr {
5859
if f == nil {
5960
return ^(uintptr(0))

src/os/file_windows.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ type file struct {
2525

2626
// Fd returns the Windows handle referencing the open file.
2727
// The handle is valid only until f.Close is called or f is garbage collected.
28+
// On Unix systems this will cause the SetDeadline methods to stop working.
2829
func (file *File) Fd() uintptr {
2930
if file == nil {
3031
return uintptr(syscall.InvalidHandle)

0 commit comments

Comments
 (0)