Skip to content
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

opt: use accept4 where available #535

Merged
merged 2 commits into from
Mar 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 6 additions & 18 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)

Expand Down
24 changes: 6 additions & 18 deletions .github/workflows/test_gc_opt.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)

Expand Down
24 changes: 6 additions & 18 deletions .github/workflows/test_poll_opt.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)

Expand Down
24 changes: 6 additions & 18 deletions .github/workflows/test_poll_opt_gc_opt.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)

Expand Down
7 changes: 0 additions & 7 deletions acceptor_bsd.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
10 changes: 1 addition & 9 deletions acceptor_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
}
11 changes: 2 additions & 9 deletions acceptor_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
package gnet

import (
"os"
"time"

"golang.org/x/sys/unix"
Expand All @@ -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:
Expand All @@ -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()))
Expand All @@ -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:
Expand All @@ -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))
Expand Down
8 changes: 4 additions & 4 deletions engine_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
})
Expand Down Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion gnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
})
Expand Down
2 changes: 1 addition & 1 deletion gnet_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
})
Expand Down
4 changes: 4 additions & 0 deletions internal/socket/sock_cloexec.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
8 changes: 8 additions & 0 deletions internal/socket/socket.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ package socket

import (
"net"

"golang.org/x/sys/unix"
)

// Option is used for setting an option on socket.
Expand All @@ -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)
}
16 changes: 14 additions & 2 deletions internal/socket/sys_cloexec.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Loading