Skip to content

Instantly share code, notes, and snippets.

@cfergeau
Created October 12, 2022 09:53
Show Gist options
  • Save cfergeau/46a4a4fda70a83dbe2a9bf519cbabd28 to your computer and use it in GitHub Desktop.
Save cfergeau/46a4a4fda70a83dbe2a9bf519cbabd28 to your computer and use it in GitHub Desktop.
go garbage collector closing reused fds
package main
import (
"fmt"
"os"
"runtime"
"time"
)
func finalizer(f *os.File) {
fmt.Println("garbage collecting os.File(fd1) created in reuseFd")
}
func reuseFd(fd uintptr) {
fmt.Println("calling NewFile on fd1")
f := os.NewFile(fd, "reuse")
go func() {
time.Sleep(50 * time.Millisecond)
runtime.SetFinalizer(f, finalizer)
}()
}
func main() {
f, err := os.Open("/dev/zero")
if err != nil {
panic(err)
}
fd1 := f.Fd()
reuseFd(fd1)
f.Close()
fmt.Println("closed fd1")
f, err = os.Open("/dev/zero")
if err != nil {
panic(err)
}
fd2 := f.Fd()
if fd1 != fd2 {
panic("failed to reuse same fd")
}
success := 0
for {
b := make([]byte, 16)
_, err = f.Read(b)
if err != nil {
fmt.Printf("read error: %v\n", err)
fmt.Printf("success count: %d\n", success)
return
}
success++
runtime.GC()
time.Sleep(100 * time.Microsecond)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment