diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 43bb891e3..f1f330ca0 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -37,18 +37,19 @@ jobs: name: Run golangci-lint runs-on: ${{ matrix.os }} steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Setup Go uses: actions/setup-go@v5 with: go-version: '^1.17' - - - name: Checkout repository - uses: actions/checkout@v4 + cache: false - name: Setup and run golangci-lint - uses: golangci/golangci-lint-action@v3 + uses: golangci/golangci-lint-action@v4 with: - version: v1.55.2 + version: v1.56.2 args: -v -E gofumpt -E gocritic -E misspell -E revive -E godot --timeout 5m test: needs: lint @@ -86,19 +87,6 @@ jobs: echo "SHORT_SHA=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT echo "GO_CACHE=$(go env GOCACHE)" >> $GITHUB_OUTPUT - - name: Cache go modules - uses: actions/cache@v4 - with: - path: | - ${{ steps.go-env.outputs.GO_CACHE }} - ~/go/pkg/mod - ~/.cache/go-build - ~/Library/Caches/go-build - ~\AppData\Local\go-build - key: ${{ runner.os }}-${{ matrix.go }}-go-ci-${{ hashFiles('**/go.sum') }} - restore-keys: | - ${{ runner.os }}-${{ matrix.go }}-go-ci- - - name: Run unit tests for packages run: go test $(go list ./... | tail -n +2) diff --git a/.github/workflows/test_gc_opt.yml b/.github/workflows/test_gc_opt.yml index 306e63f18..2cd709ce5 100644 --- a/.github/workflows/test_gc_opt.yml +++ b/.github/workflows/test_gc_opt.yml @@ -37,18 +37,19 @@ jobs: name: Run golangci-lint runs-on: ${{ matrix.os }} steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Setup Go uses: actions/setup-go@v5 with: go-version: '^1.17' - - - name: Checkout repository - uses: actions/checkout@v4 + cache: false - name: Setup and run golangci-lint - uses: golangci/golangci-lint-action@v3 + uses: golangci/golangci-lint-action@v4 with: - version: v1.55.2 + version: v1.56.2 args: -v -E gofumpt -E gocritic -E misspell -E revive -E godot --timeout 5m test: needs: lint @@ -86,19 +87,6 @@ jobs: echo "SHORT_SHA=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT echo "GO_CACHE=$(go env GOCACHE)" >> $GITHUB_OUTPUT - - name: Cache go modules - uses: actions/cache@v4 - with: - path: | - ${{ steps.go-env.outputs.GO_CACHE }} - ~/go/pkg/mod - ~/.cache/go-build - ~/Library/Caches/go-build - ~\AppData\Local\go-build - key: ${{ runner.os }}-${{ matrix.go }}-go-ci-${{ hashFiles('**/go.sum') }} - restore-keys: | - ${{ runner.os }}-${{ matrix.go }}-go-ci- - - name: Run unit tests for packages run: go test $(go list ./... | tail -n +2) diff --git a/.github/workflows/test_poll_opt.yml b/.github/workflows/test_poll_opt.yml index f5613a49b..47b7a63d4 100644 --- a/.github/workflows/test_poll_opt.yml +++ b/.github/workflows/test_poll_opt.yml @@ -36,18 +36,19 @@ jobs: name: Run golangci-lint runs-on: ${{ matrix.os }} steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Setup Go uses: actions/setup-go@v5 with: go-version: '^1.17' - - - name: Checkout repository - uses: actions/checkout@v4 + cache: false - name: Setup and run golangci-lint - uses: golangci/golangci-lint-action@v3 + uses: golangci/golangci-lint-action@v4 with: - version: v1.55.2 + version: v1.56.2 args: -v -E gofumpt -E gocritic -E misspell -E revive -E godot test: needs: lint @@ -82,19 +83,6 @@ jobs: echo "SHORT_SHA=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT echo "GO_CACHE=$(go env GOCACHE)" >> $GITHUB_OUTPUT - - name: Cache go modules - uses: actions/cache@v4 - with: - path: | - ${{ steps.go-env.outputs.GO_CACHE }} - ~/go/pkg/mod - ~/.cache/go-build - ~/Library/Caches/go-build - ~\AppData\Local\go-build - key: ${{ runner.os }}-${{ matrix.go }}-go-ci-${{ hashFiles('**/go.sum') }} - restore-keys: | - ${{ runner.os }}-${{ matrix.go }}-go-ci- - - name: Run unit tests for packages run: go test $(go list ./... | tail -n +2) diff --git a/.github/workflows/test_poll_opt_gc_opt.yml b/.github/workflows/test_poll_opt_gc_opt.yml index dc4b2cf92..1f117bbd9 100644 --- a/.github/workflows/test_poll_opt_gc_opt.yml +++ b/.github/workflows/test_poll_opt_gc_opt.yml @@ -36,18 +36,19 @@ jobs: name: Run golangci-lint runs-on: ${{ matrix.os }} steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Setup Go uses: actions/setup-go@v5 with: go-version: '^1.17' - - - name: Checkout repository - uses: actions/checkout@v4 + cache: false - name: Setup and run golangci-lint - uses: golangci/golangci-lint-action@v3 + uses: golangci/golangci-lint-action@v4 with: - version: v1.55.2 + version: v1.56.2 args: -v -E gofumpt -E gocritic -E misspell -E revive -E godot test: needs: lint @@ -82,19 +83,6 @@ jobs: echo "SHORT_SHA=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT echo "GO_CACHE=$(go env GOCACHE)" >> $GITHUB_OUTPUT - - name: Cache go modules - uses: actions/cache@v4 - with: - path: | - ${{ steps.go-env.outputs.GO_CACHE }} - ~/go/pkg/mod - ~/.cache/go-build - ~/Library/Caches/go-build - ~\AppData\Local\go-build - key: ${{ runner.os }}-${{ matrix.go }}-go-ci-${{ hashFiles('**/go.sum') }} - restore-keys: | - ${{ runner.os }}-${{ matrix.go }}-go-ci- - - name: Run unit tests for packages run: go test $(go list ./... | tail -n +2) diff --git a/acceptor_bsd.go b/acceptor_bsd.go index 879897b85..3b717e3b0 100644 --- a/acceptor_bsd.go +++ b/acceptor_bsd.go @@ -26,10 +26,3 @@ func (eng *engine) accept(fd int, filter netpoll.IOEvent, flags netpoll.IOFlags) func (el *eventloop) accept(fd int, filter netpoll.IOEvent, flags netpoll.IOFlags) error { return el.accept1(fd, filter, flags) } - -// The canonical BSD sockets implementation will inherit file status flags -// from the listening socket, so we don't need to set the non-blocking flag -// for the accepted sockets explicitly. -func setNonBlock(_ int, _ bool) error { - return nil -} diff --git a/acceptor_linux.go b/acceptor_linux.go index 1989cd83a..04931b64c 100644 --- a/acceptor_linux.go +++ b/acceptor_linux.go @@ -17,11 +17,7 @@ package gnet -import ( - "golang.org/x/sys/unix" - - "github.com/panjf2000/gnet/v2/internal/netpoll" -) +import "github.com/panjf2000/gnet/v2/internal/netpoll" func (eng *engine) accept(fd int, ev netpoll.IOEvent) error { return eng.accept1(fd, ev, 0) @@ -30,7 +26,3 @@ func (eng *engine) accept(fd int, ev netpoll.IOEvent) error { func (el *eventloop) accept(fd int, ev netpoll.IOEvent) error { return el.accept1(fd, ev, 0) } - -func setNonBlock(fd int, nonBlocking bool) error { - return unix.SetNonblock(fd, nonBlocking) -} diff --git a/acceptor_unix.go b/acceptor_unix.go index 2d55b0759..cb752c60b 100644 --- a/acceptor_unix.go +++ b/acceptor_unix.go @@ -18,7 +18,6 @@ package gnet import ( - "os" "time" "golang.org/x/sys/unix" @@ -30,7 +29,7 @@ import ( ) func (eng *engine) accept1(fd int, _ netpoll.IOEvent, _ netpoll.IOFlags) error { - nfd, sa, err := unix.Accept(fd) + nfd, sa, err := socket.Accept(fd) if err != nil { switch err { case unix.EINTR, unix.EAGAIN, unix.ECONNABORTED: @@ -44,9 +43,6 @@ func (eng *engine) accept1(fd int, _ netpoll.IOEvent, _ netpoll.IOFlags) error { } } - if err = os.NewSyscallError("fcntl nonblock", setNonBlock(nfd, true)); err != nil { - return err - } remoteAddr := socket.SockaddrToTCPOrUnixAddr(sa) if eng.opts.TCPKeepAlive > 0 && eng.ln.network == "tcp" { err = socket.SetKeepAlivePeriod(nfd, int(eng.opts.TCPKeepAlive.Seconds())) @@ -69,7 +65,7 @@ func (el *eventloop) accept1(fd int, ev netpoll.IOEvent, flags netpoll.IOFlags) return el.readUDP1(fd, ev, flags) } - nfd, sa, err := unix.Accept(el.ln.fd) + nfd, sa, err := socket.Accept(el.ln.fd) if err != nil { switch err { case unix.EINTR, unix.EAGAIN, unix.ECONNABORTED: @@ -83,9 +79,6 @@ func (el *eventloop) accept1(fd int, ev netpoll.IOEvent, flags netpoll.IOFlags) } } - if err = os.NewSyscallError("fcntl nonblock", setNonBlock(nfd, true)); err != nil { - return err - } remoteAddr := socket.SockaddrToTCPOrUnixAddr(sa) if el.engine.opts.TCPKeepAlive > 0 && el.ln.network == "tcp" { err = socket.SetKeepAlivePeriod(nfd, int(el.engine.opts.TCPKeepAlive/time.Second)) diff --git a/engine_unix.go b/engine_unix.go index 26af89c99..3d2fc9cf2 100644 --- a/engine_unix.go +++ b/engine_unix.go @@ -66,14 +66,14 @@ func (eng *engine) shutdown(err error) { } func (eng *engine) startEventLoops() { - eng.eventLoops.iterate(func(i int, el *eventloop) bool { + eng.eventLoops.iterate(func(_ int, el *eventloop) bool { eng.workerPool.Go(el.run) return true }) } func (eng *engine) closeEventLoops() { - eng.eventLoops.iterate(func(i int, el *eventloop) bool { + eng.eventLoops.iterate(func(_ int, el *eventloop) bool { el.ln.close() _ = el.poller.Close() return true @@ -88,7 +88,7 @@ func (eng *engine) closeEventLoops() { } func (eng *engine) startSubReactors() { - eng.eventLoops.iterate(func(i int, el *eventloop) bool { + eng.eventLoops.iterate(func(_ int, el *eventloop) bool { eng.workerPool.Go(el.activateSubReactor) return true }) @@ -202,7 +202,7 @@ func (eng *engine) stop(s Engine) { eng.eventHandler.OnShutdown(s) // Notify all event-loops to exit. - eng.eventLoops.iterate(func(i int, el *eventloop) bool { + eng.eventLoops.iterate(func(_ int, el *eventloop) bool { err := el.poller.UrgentTrigger(func(_ interface{}) error { return errors.ErrEngineShutdown }, nil) if err != nil { eng.opts.Logger.Errorf("failed to call UrgentTrigger on sub event-loop when stopping engine: %v", err) diff --git a/gnet.go b/gnet.go index fd3098913..f77ee5793 100644 --- a/gnet.go +++ b/gnet.go @@ -65,7 +65,7 @@ func (e Engine) CountConnections() (count int) { return -1 } - e.eng.eventLoops.iterate(func(i int, el *eventloop) bool { + e.eng.eventLoops.iterate(func(_ int, el *eventloop) bool { count += int(el.countConn()) return true }) diff --git a/gnet_test.go b/gnet_test.go index 23446a965..36bba8c73 100644 --- a/gnet_test.go +++ b/gnet_test.go @@ -886,7 +886,7 @@ func (t *testCloseConnectionServer) OnTraffic(c Conn) (action Action) { _, _ = c.Discard(-1) go func() { time.Sleep(time.Second) - _ = c.CloseWithCallback(func(c Conn, err error) error { + _ = c.CloseWithCallback(func(_ Conn, err error) error { assert.ErrorIsf(t.tester, err, errorx.ErrEngineShutdown, "should be engine shutdown error") return nil }) diff --git a/internal/socket/sock_cloexec.go b/internal/socket/sock_cloexec.go index 1c861f95c..4be0813a1 100644 --- a/internal/socket/sock_cloexec.go +++ b/internal/socket/sock_cloexec.go @@ -22,3 +22,7 @@ import "golang.org/x/sys/unix" func sysSocket(family, sotype, proto int) (int, error) { return unix.Socket(family, sotype|unix.SOCK_NONBLOCK|unix.SOCK_CLOEXEC, proto) } + +func sysAccept(fd int) (nfd int, sa unix.Sockaddr, err error) { + return unix.Accept4(fd, unix.SOCK_NONBLOCK|unix.SOCK_CLOEXEC) +} diff --git a/internal/socket/socket.go b/internal/socket/socket.go index 4215304fe..e49f143f3 100644 --- a/internal/socket/socket.go +++ b/internal/socket/socket.go @@ -22,6 +22,8 @@ package socket import ( "net" + + "golang.org/x/sys/unix" ) // Option is used for setting an option on socket. @@ -44,3 +46,9 @@ func UDPSocket(proto, addr string, connect bool, sockOpts ...Option) (int, net.A func UnixSocket(proto, addr string, passive bool, sockOpts ...Option) (int, net.Addr, error) { return udsSocket(proto, addr, passive, sockOpts...) } + +// Accept accepts the next incoming socket along with setting +// O_NONBLOCK and O_CLOEXEC flags on it. +func Accept(fd int) (int, unix.Sockaddr, error) { + return sysAccept(fd) +} diff --git a/internal/socket/sys_cloexec.go b/internal/socket/sys_cloexec.go index 889036ab1..b526c100d 100644 --- a/internal/socket/sys_cloexec.go +++ b/internal/socket/sys_cloexec.go @@ -29,14 +29,26 @@ func sysSocket(family, sotype, proto int) (fd int, err error) { unix.CloseOnExec(fd) } syscall.ForkLock.RUnlock() - if err != nil { return } - if err = unix.SetNonblock(fd, true); err != nil { _ = unix.Close(fd) } + return +} +func sysAccept(fd int) (nfd int, sa unix.Sockaddr, err error) { + syscall.ForkLock.RLock() + if nfd, sa, err = unix.Accept(fd); err == nil { + unix.CloseOnExec(nfd) + } + syscall.ForkLock.RUnlock() + if err != nil { + return + } + if err = unix.SetNonblock(nfd, true); err != nil { + _ = unix.Close(nfd) + } return }