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
Changes from 1 commit
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
Next Next commit
opt: use accept4 where available
  • Loading branch information
panjf2000 committed Mar 2, 2024
commit 518f74ab85875176856c49d1a7f0d82e601c10a0
7 changes: 0 additions & 7 deletions acceptor_bsd.go
Original file line number Diff line number Diff line change
@@ -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
@@ -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)
}
11 changes: 2 additions & 9 deletions acceptor_unix.go
Original file line number Diff line number Diff line change
@@ -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))
8 changes: 4 additions & 4 deletions engine_unix.go
Original file line number Diff line number Diff line change
@@ -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)
2 changes: 1 addition & 1 deletion gnet.go
Original file line number Diff line number Diff line change
@@ -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
})
2 changes: 1 addition & 1 deletion gnet_test.go
Original file line number Diff line number Diff line change
@@ -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
})
4 changes: 4 additions & 0 deletions internal/socket/sock_cloexec.go
Original file line number Diff line number Diff line change
@@ -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
@@ -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)
}
16 changes: 14 additions & 2 deletions internal/socket/sys_cloexec.go
Original file line number Diff line number Diff line change
@@ -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