Skip to content

Instantly share code, notes, and snippets.

@lspgn
Created March 20, 2022 04:50
Show Gist options
  • Save lspgn/69fa0110698240eca9e465628277f5ce to your computer and use it in GitHub Desktop.
Save lspgn/69fa0110698240eca9e465628277f5ce to your computer and use it in GitHub Desktop.
Golang File Descriptor Block Issue
package main
import (
"fmt"
"net"
"log"
"flag"
"context"
"syscall"
"time"
)
var (
listen = flag.String("listen", ":8000", "listen address")
bug = flag.Bool("bug", true, "trigger bug")
fix = flag.Bool("fix", false, "trigger fix")
)
func main() {
flag.Parse()
fmt.Println("Bug test with FD")
ctx := context.Background()
config := net.ListenConfig{}
lis, err := config.Listen(ctx, "tcp", *listen)
if err != nil {
log.Fatal(err)
}
lisAddr := lis.Addr().String()
fmt.Println("Listening", lisAddr)
lisTcp := lis.(*net.TCPListener)
f, err := lisTcp.File()
if err != nil {
log.Fatal(err)
}
if *bug {
fd := f.Fd()
fdi := int(fd)
fmt.Println("FDI", fd, fdi)
if *fix {
syscall.SetNonblock(fdi, true)
}
}
go func() {
fmt.Println("Will close in 2 seconds")
select {
case <-time.After(time.Second*2):
f.Close()
fmt.Println("Trigger close")
lis.Close()
}
fmt.Println("Close done")
}()
for {
conn, err := lisTcp.AcceptTCP()
if err != nil {
log.Println("Error accepting", err)
break
}
fmt.Println("Accepted connection", conn)
conn.Write([]byte("Hello world!"))
conn.Close()
}
fmt.Println("Done")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment