From 9d477932d7834dc660a976c427ba923dbd79d452 Mon Sep 17 00:00:00 2001 From: wineguo Date: Thu, 4 May 2023 12:42:45 +0800 Subject: [PATCH 01/17] tcp{service|listener}: wrap more information into error message From 78ff24315c0b6899e744c4a7e84a1961f3c72150 Mon Sep 17 00:00:00 2001 From: wineguo Date: Mon, 8 May 2023 10:01:32 +0800 Subject: [PATCH 02/17] accept: pass non block flag to accept4 From bd2d67a01a5e8bcc7b336f0c8bd8c8aeb9a519ac Mon Sep 17 00:00:00 2001 From: wineguo Date: Mon, 8 May 2023 14:34:40 +0800 Subject: [PATCH 03/17] log: provide customized logging package From 33dd8e68e29d85bae9c04c3d845c33fbee9cde1f Mon Sep 17 00:00:00 2001 From: wineguo Date: Thu, 18 May 2023 15:19:33 +0800 Subject: [PATCH 04/17] internal/poller: add ignore task error to poller manager From 8a1cf580b545b3a1a4caf6e0d7e543e83d7d861c Mon Sep 17 00:00:00 2001 From: wineguo Date: Fri, 30 Jun 2023 10:25:02 +0800 Subject: [PATCH 05/17] none From 0a2de39bbda673cd2b8c73569cb4c1db7a57c885 Mon Sep 17 00:00:00 2001 From: wineguo Date: Mon, 3 Jul 2023 10:49:08 +0800 Subject: [PATCH 06/17] tnet: check nil pointer for on hup From 5c51bd2dbfc8910b24509bed1e4c6b1c1ce7a006 Mon Sep 17 00:00:00 2001 From: wineguo Date: Mon, 3 Jul 2023 11:00:57 +0800 Subject: [PATCH 07/17] tnet: check tcp service onRead/onHup nil pointer From 83c5cb8d3757abb08ce49d2d83c70fe95f7e5bf0 Mon Sep 17 00:00:00 2001 From: wineguo Date: Tue, 18 Jul 2023 20:02:41 +0800 Subject: [PATCH 08/17] tls: support SetOnRequest, SetOnClosed and IsActive --- tls/tls_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tls/tls_test.go b/tls/tls_test.go index 82b18f4..4bbf7e9 100644 --- a/tls/tls_test.go +++ b/tls/tls_test.go @@ -385,9 +385,11 @@ func runTestWithHandlesOnRequestOnClose( conn, err := tls.Dial("tcp", addr, dialOpts...) require.Nil(t, err) conn.SetOnRequest(func(_ tls.Conn) error { + t.Logf("on request\n") return nil }) conn.SetOnClosed(func(_ tls.Conn) error { + t.Logf("closed\n") return nil }) require.Nil(t, clientHandle(conn)) From dec553c5beefb163efd950e44c5d7c446ea6279b Mon Sep 17 00:00:00 2001 From: leoxhyang Date: Wed, 2 Aug 2023 17:20:12 +0800 Subject: [PATCH 09/17] tnet/tls: fix onRequest not triggering (merge request !198) Squash merge branch 'tls-onrequest' into 'master' Inside the crypto/tls, there is an internal buffer to store data. When the tnet buffer is empty but there is data present in the crypto/tls buffer, the onRequest function does not trigger. In order to ensure that user can read all the data from connection, use a loop in tls onRequest. TAPD: --story=886307227 --- tls/tls_test.go | 58 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/tls/tls_test.go b/tls/tls_test.go index 4bbf7e9..c521468 100644 --- a/tls/tls_test.go +++ b/tls/tls_test.go @@ -260,6 +260,62 @@ func TestClientAndServerForHighConcurrency(t *testing.T) { <-done } +func TestClientAndServerForHighConcurrency(t *testing.T) { + done := make(chan struct{}) + cancel := runServer(t, func(c tls.Conn) error { + buf := make([]byte, 20) + n, err := c.Read(buf) + if errors.Is(err, tnet.ErrConnClosed) { + return err + } + require.Nil(t, err) + require.Equal(t, 20, n) + n, err = c.Write(buf) + require.Nil(t, err) + require.Equal(t, 20, n) + return nil + }, done, tls.WithServerTLSConfig(getTLSCfg())) + conn, err := tls.Dial("tcp", addr, tls.WithClientTLSConfig(&stdtls.Config{InsecureSkipVerify: true})) + require.Nil(t, err) + buf := make([]byte, 20) + rand.Read(buf) + var ( + wg sync.WaitGroup + concurrent = 100 + reqNum = 100 + ) + wg.Add(concurrent * reqNum) + conn.SetOnRequest(func(c tls.Conn) error { + data := make([]byte, 20) + n, err := conn.Read(data) + if errors.Is(err, tnet.ErrConnClosed) { + return err + } + require.Nil(t, err) + require.Equal(t, 20, n) + require.Equal(t, buf, data) + wg.Done() + return nil + }) + for i := 0; i < concurrent; i++ { + go func() { + for i := 0; i < reqNum; i++ { + n, err := conn.Write(buf) + require.Nil(t, err) + require.Equal(t, 20, n) + } + }() + } + require.Eventually(t, + func() bool { + wg.Wait() + return true + }, time.Second, time.Millisecond*200, + "The onRequest of the client is not triggered enough times, some responses are missed.") + cancel() + <-done +} + func BenchmarkTNetClientServer(b *testing.B) { buf := make([]byte, 5) ln, err := tnet.Listen("tcp", listenAddr) @@ -385,11 +441,9 @@ func runTestWithHandlesOnRequestOnClose( conn, err := tls.Dial("tcp", addr, dialOpts...) require.Nil(t, err) conn.SetOnRequest(func(_ tls.Conn) error { - t.Logf("on request\n") return nil }) conn.SetOnClosed(func(_ tls.Conn) error { - t.Logf("closed\n") return nil }) require.Nil(t, clientHandle(conn)) From 27d9dc1cc118cf083f570e8b43d34d7bbab8bc05 Mon Sep 17 00:00:00 2001 From: leoxhyang Date: Wed, 9 Aug 2023 15:19:40 +0800 Subject: [PATCH 10/17] poller: fix desc race condition --- tls/tls_test.go | 56 ------------------------------------------------- 1 file changed, 56 deletions(-) diff --git a/tls/tls_test.go b/tls/tls_test.go index c521468..82b18f4 100644 --- a/tls/tls_test.go +++ b/tls/tls_test.go @@ -260,62 +260,6 @@ func TestClientAndServerForHighConcurrency(t *testing.T) { <-done } -func TestClientAndServerForHighConcurrency(t *testing.T) { - done := make(chan struct{}) - cancel := runServer(t, func(c tls.Conn) error { - buf := make([]byte, 20) - n, err := c.Read(buf) - if errors.Is(err, tnet.ErrConnClosed) { - return err - } - require.Nil(t, err) - require.Equal(t, 20, n) - n, err = c.Write(buf) - require.Nil(t, err) - require.Equal(t, 20, n) - return nil - }, done, tls.WithServerTLSConfig(getTLSCfg())) - conn, err := tls.Dial("tcp", addr, tls.WithClientTLSConfig(&stdtls.Config{InsecureSkipVerify: true})) - require.Nil(t, err) - buf := make([]byte, 20) - rand.Read(buf) - var ( - wg sync.WaitGroup - concurrent = 100 - reqNum = 100 - ) - wg.Add(concurrent * reqNum) - conn.SetOnRequest(func(c tls.Conn) error { - data := make([]byte, 20) - n, err := conn.Read(data) - if errors.Is(err, tnet.ErrConnClosed) { - return err - } - require.Nil(t, err) - require.Equal(t, 20, n) - require.Equal(t, buf, data) - wg.Done() - return nil - }) - for i := 0; i < concurrent; i++ { - go func() { - for i := 0; i < reqNum; i++ { - n, err := conn.Write(buf) - require.Nil(t, err) - require.Equal(t, 20, n) - } - }() - } - require.Eventually(t, - func() bool { - wg.Wait() - return true - }, time.Second, time.Millisecond*200, - "The onRequest of the client is not triggered enough times, some responses are missed.") - cancel() - <-done -} - func BenchmarkTNetClientServer(b *testing.B) { buf := make([]byte, 5) ln, err := tnet.Listen("tcp", listenAddr) From cc7d89dd6ce9af4528f00faf390d7c5dcb352337 Mon Sep 17 00:00:00 2001 From: leoxhyang Date: Fri, 11 Aug 2023 17:52:07 +0800 Subject: [PATCH 11/17] timer: fix unit test (merge request !206) Squash merge branch 'fix-timer-test' into 'master' timer: fix unit test TAPD: --story=886587517 --- internal/timer/timer_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/internal/timer/timer_test.go b/internal/timer/timer_test.go index 2cf0b78..de87b0c 100644 --- a/internal/timer/timer_test.go +++ b/internal/timer/timer_test.go @@ -21,7 +21,6 @@ func TestTimerNormal(t *testing.T) { time.Sleep(time.Millisecond * 10) assert.Equal(t, true, t1.Expired()) - t1.Start() t1.Reset(time.Time{}) assert.Equal(t, true, t1.IsZero()) assert.Equal(t, false, t1.Expired()) From 0353d83a847267c6d88a65365560a19c43b3d3f8 Mon Sep 17 00:00:00 2001 From: wineguo Date: Fri, 15 Sep 2023 15:49:47 +0800 Subject: [PATCH 12/17] poller: add multi-arch for epoll event data --- internal/poller/event/defs_linux_386.go | 14 ++++++ internal/poller/event/defs_linux_amd64.go | 14 ++++++ internal/poller/event/defs_linux_arm.go | 15 +++++++ internal/poller/event/defs_linux_arm64.go | 15 +++++++ internal/poller/event/defs_linux_loong64.go | 15 +++++++ internal/poller/event/defs_linux_mips64x.go | 17 ++++++++ internal/poller/event/defs_linux_mipsx.go | 17 ++++++++ internal/poller/event/defs_linux_ppc64x.go | 17 ++++++++ internal/poller/event/defs_linux_riscv64.go | 15 +++++++ internal/poller/event/defs_linux_s390x.go | 15 +++++++ internal/poller/poller_epoll.go | 48 ++++++++++----------- 11 files changed, 176 insertions(+), 26 deletions(-) create mode 100644 internal/poller/event/defs_linux_386.go create mode 100644 internal/poller/event/defs_linux_amd64.go create mode 100644 internal/poller/event/defs_linux_arm.go create mode 100644 internal/poller/event/defs_linux_arm64.go create mode 100644 internal/poller/event/defs_linux_loong64.go create mode 100644 internal/poller/event/defs_linux_mips64x.go create mode 100644 internal/poller/event/defs_linux_mipsx.go create mode 100644 internal/poller/event/defs_linux_ppc64x.go create mode 100644 internal/poller/event/defs_linux_riscv64.go create mode 100644 internal/poller/event/defs_linux_s390x.go diff --git a/internal/poller/event/defs_linux_386.go b/internal/poller/event/defs_linux_386.go new file mode 100644 index 0000000..1056365 --- /dev/null +++ b/internal/poller/event/defs_linux_386.go @@ -0,0 +1,14 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +// +// This file may have been modified by THL A29 Limited ("Tencent Modifications"). +// All Tencent Modifications are Copyright (C) 2023 THL A29 Limited. + +package event + +// EpollEvent defines epoll event data. +type EpollEvent struct { + Events uint32 + Data [8]byte // to match amd64 +} diff --git a/internal/poller/event/defs_linux_amd64.go b/internal/poller/event/defs_linux_amd64.go new file mode 100644 index 0000000..2359873 --- /dev/null +++ b/internal/poller/event/defs_linux_amd64.go @@ -0,0 +1,14 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +// +// This file may have been modified by THL A29 Limited ("Tencent Modifications"). +// All Tencent Modifications are Copyright (C) 2023 THL A29 Limited. + +package event + +// EpollEvent defines epoll event data. +type EpollEvent struct { + Events uint32 + Data [8]byte // unaligned uintptr +} diff --git a/internal/poller/event/defs_linux_arm.go b/internal/poller/event/defs_linux_arm.go new file mode 100644 index 0000000..1d0b52d --- /dev/null +++ b/internal/poller/event/defs_linux_arm.go @@ -0,0 +1,15 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +// +// This file may have been modified by THL A29 Limited ("Tencent Modifications"). +// All Tencent Modifications are Copyright (C) 2023 THL A29 Limited. + +package event + +// EpollEvent defines epoll event data. +type EpollEvent struct { + Events uint32 + _pad uint32 + Data [8]byte // to match amd64 +} diff --git a/internal/poller/event/defs_linux_arm64.go b/internal/poller/event/defs_linux_arm64.go new file mode 100644 index 0000000..1d0b52d --- /dev/null +++ b/internal/poller/event/defs_linux_arm64.go @@ -0,0 +1,15 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +// +// This file may have been modified by THL A29 Limited ("Tencent Modifications"). +// All Tencent Modifications are Copyright (C) 2023 THL A29 Limited. + +package event + +// EpollEvent defines epoll event data. +type EpollEvent struct { + Events uint32 + _pad uint32 + Data [8]byte // to match amd64 +} diff --git a/internal/poller/event/defs_linux_loong64.go b/internal/poller/event/defs_linux_loong64.go new file mode 100644 index 0000000..de57a65 --- /dev/null +++ b/internal/poller/event/defs_linux_loong64.go @@ -0,0 +1,15 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +// +// This file may have been modified by THL A29 Limited ("Tencent Modifications"). +// All Tencent Modifications are Copyright (C) 2023 THL A29 Limited. + +package event + +// EpollEvent defines epoll event data. +type EpollEvent struct { + Events uint32 + pad_cgo_0 [4]byte + Data [8]byte // unaligned uintptr +} diff --git a/internal/poller/event/defs_linux_mips64x.go b/internal/poller/event/defs_linux_mips64x.go new file mode 100644 index 0000000..7da8ae0 --- /dev/null +++ b/internal/poller/event/defs_linux_mips64x.go @@ -0,0 +1,17 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +// +// This file may have been modified by THL A29 Limited ("Tencent Modifications"). +// All Tencent Modifications are Copyright (C) 2023 THL A29 Limited. + +//go:build linux && (mips64 || mips64le) + +package event + +// EpollEvent defines epoll event data. +type EpollEvent struct { + Events uint32 + pad_cgo_0 [4]byte + Data [8]byte // unaligned uintptr +} diff --git a/internal/poller/event/defs_linux_mipsx.go b/internal/poller/event/defs_linux_mipsx.go new file mode 100644 index 0000000..1345447 --- /dev/null +++ b/internal/poller/event/defs_linux_mipsx.go @@ -0,0 +1,17 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +// +// This file may have been modified by THL A29 Limited ("Tencent Modifications"). +// All Tencent Modifications are Copyright (C) 2023 THL A29 Limited. + +//go:build linux && (mips || mipsle) + +package event + +// EpollEvent defines epoll event data. +type EpollEvent struct { + Events uint32 + pad_cgo_0 [4]byte + Data uint64 +} diff --git a/internal/poller/event/defs_linux_ppc64x.go b/internal/poller/event/defs_linux_ppc64x.go new file mode 100644 index 0000000..8465f3d --- /dev/null +++ b/internal/poller/event/defs_linux_ppc64x.go @@ -0,0 +1,17 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +// +// This file may have been modified by THL A29 Limited ("Tencent Modifications"). +// All Tencent Modifications are Copyright (C) 2023 THL A29 Limited. + +//go:build linux && (ppc64 || ppc64le) + +package event + +// EpollEvent defines epoll event data. +type EpollEvent struct { + Events uint32 + pad_cgo_0 [4]byte + Data [8]byte // unaligned uintptr +} diff --git a/internal/poller/event/defs_linux_riscv64.go b/internal/poller/event/defs_linux_riscv64.go new file mode 100644 index 0000000..de57a65 --- /dev/null +++ b/internal/poller/event/defs_linux_riscv64.go @@ -0,0 +1,15 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +// +// This file may have been modified by THL A29 Limited ("Tencent Modifications"). +// All Tencent Modifications are Copyright (C) 2023 THL A29 Limited. + +package event + +// EpollEvent defines epoll event data. +type EpollEvent struct { + Events uint32 + pad_cgo_0 [4]byte + Data [8]byte // unaligned uintptr +} diff --git a/internal/poller/event/defs_linux_s390x.go b/internal/poller/event/defs_linux_s390x.go new file mode 100644 index 0000000..de57a65 --- /dev/null +++ b/internal/poller/event/defs_linux_s390x.go @@ -0,0 +1,15 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +// +// This file may have been modified by THL A29 Limited ("Tencent Modifications"). +// All Tencent Modifications are Copyright (C) 2023 THL A29 Limited. + +package event + +// EpollEvent defines epoll event data. +type EpollEvent struct { + Events uint32 + pad_cgo_0 [4]byte + Data [8]byte // unaligned uintptr +} diff --git a/internal/poller/poller_epoll.go b/internal/poller/poller_epoll.go index 89bcda2..536819f 100644 --- a/internal/poller/poller_epoll.go +++ b/internal/poller/poller_epoll.go @@ -19,6 +19,7 @@ import ( "github.com/pkg/errors" "golang.org/x/sys/unix" "trpc.group/trpc-go/tnet/internal/iovec" + "trpc.group/trpc-go/tnet/internal/poller/event" "trpc.group/trpc-go/tnet/log" "trpc.group/trpc-go/tnet/metrics" ) @@ -45,7 +46,7 @@ func newPoller(ignoreTaskError bool) (Poller, error) { poller := &epoll{ fd: fd, desc: desc, - events: make([]epollevent, defaultEventCount), + events: make([]event.EpollEvent, defaultEventCount), ioData: iovec.NewIOData(), buf: make([]byte, 8), ignoreTaskError: ignoreTaskError, @@ -61,13 +62,13 @@ type epoll struct { desc *Desc ioData iovec.IOData buf []byte - events []epollevent + events []event.EpollEvent fd int notified int32 ignoreTaskError bool } -func epollWait(epfd int, events []epollevent, msec int) (n int, err error) { +func epollWait(epfd int, events []event.EpollEvent, msec int) (n int, err error) { var r0 uintptr var _p0 = unsafe.Pointer(&events[0]) if msec == 0 { @@ -118,7 +119,7 @@ func (ep *epoll) handle(n int) { var wakeUp bool for i := 0; i < n; i++ { event := ep.events[i] - desc := *(**Desc)(unsafe.Pointer(&event.data)) + desc := *(**Desc)(unsafe.Pointer(&event.Data)) if desc.FD == ep.desc.FD { _, _ = unix.Read(ep.desc.FD, ep.buf) wakeUp = true @@ -128,11 +129,11 @@ func (ep *epoll) handle(n int) { var inHup bool // Read/Write and error events may be triggered at the same time, // so use if/else instead of switch/case to determine them separately. - if event.events&(unix.EPOLLHUP|unix.EPOLLRDHUP|unix.EPOLLERR) != 0 { + if event.Events&(unix.EPOLLHUP|unix.EPOLLRDHUP|unix.EPOLLERR) != 0 { inHup = true } - readable := event.events&(unix.EPOLLIN|unix.EPOLLPRI) != 0 - writable := event.events&(unix.EPOLLOUT) != 0 + readable := event.Events&(unix.EPOLLIN|unix.EPOLLPRI) != 0 + writable := event.Events&(unix.EPOLLOUT) != 0 // The handler function may change at runtime, so for consistency, // we store them in a temporary variable. onRead, onWrite, data := desc.OnRead, desc.OnWrite, desc.Data @@ -206,32 +207,32 @@ func (ep *epoll) Trigger(job Job) error { } // Control the event of Desc and the operations is defined by Event. -func (ep *epoll) Control(desc *Desc, event Event) (err error) { - evt := &epollevent{} - *(**Desc)(unsafe.Pointer(&evt.data)) = desc +func (ep *epoll) Control(desc *Desc, e Event) (err error) { + evt := &event.EpollEvent{} + *(**Desc)(unsafe.Pointer(&evt.Data)) = desc defer func() { if err != nil { // Prevent unconditional execution of fmt.Sprintf. - err = errors.Wrap(err, fmt.Sprintf("event: %s, connection may be closed", event)) + err = errors.Wrap(err, fmt.Sprintf("event: %s, connection may be closed", e)) } }() - switch event { + switch e { case Readable: - evt.events = rflags + evt.Events = rflags return ep.insert(desc.FD, evt) case Writable: - evt.events = wflags + evt.Events = wflags return ep.insert(desc.FD, evt) case ReadWriteable: - evt.events = rflags | wflags + evt.Events = rflags | wflags return ep.insert(desc.FD, evt) case ModReadable: - evt.events = rflags + evt.Events = rflags return ep.interest(desc.FD, evt) case ModWritable: - evt.events = wflags + evt.Events = wflags return ep.interest(desc.FD, evt) case ModReadWriteable: - evt.events = rflags | wflags + evt.Events = rflags | wflags return ep.interest(desc.FD, evt) case Detach: return ep.remove(desc.FD) @@ -240,14 +241,14 @@ func (ep *epoll) Control(desc *Desc, event Event) (err error) { } } -func (ep *epoll) insert(fd int, event *epollevent) error { +func (ep *epoll) insert(fd int, event *event.EpollEvent) error { if err := epollCtl(ep.fd, unix.EPOLL_CTL_ADD, fd, event); err != nil { return os.NewSyscallError("epoll_ctl add", err) } return nil } -func (ep *epoll) interest(fd int, event *epollevent) error { +func (ep *epoll) interest(fd int, event *event.EpollEvent) error { if err := epollCtl(ep.fd, unix.EPOLL_CTL_MOD, fd, event); err != nil { return os.NewSyscallError("epoll_ctl mod", err) } @@ -261,12 +262,7 @@ func (ep *epoll) remove(fd int) error { return nil } -type epollevent struct { - events uint32 - data [8]byte -} - -func epollCtl(epfd int, op int, fd int, event *epollevent) error { +func epollCtl(epfd int, op int, fd int, event *event.EpollEvent) error { var err error _, _, err = unix.RawSyscall6( unix.SYS_EPOLL_CTL, From a01b331557d00423be82dd4569753719c8975d90 Mon Sep 17 00:00:00 2001 From: wineguo Date: Wed, 20 Sep 2023 17:42:13 +0800 Subject: [PATCH 13/17] poller: add flag to switch on runtime.Gosched after handling events (merge request !211) Squash merge branch 'v0.0.16-sched-in-wait-inner-loop-global-var' into 'master' poller: add flag to switch on runtime.Gosched after handling events close #6 TAPD: --story=887517909 --- internal/poller/poller.go | 5 +++++ internal/poller/poller_epoll.go | 3 +++ internal/poller/poller_kqueue.go | 3 +++ options.go | 7 +++++++ 4 files changed, 18 insertions(+) diff --git a/internal/poller/poller.go b/internal/poller/poller.go index ecc63bd..387bdfc 100644 --- a/internal/poller/poller.go +++ b/internal/poller/poller.go @@ -9,6 +9,11 @@ package poller import "fmt" +// GoschedAfterEvent decides whether to call runtime.Gosched() after processing of each event +// during epoll waiting handling. +// This global variable can only be changed inside func init(). +var GoschedAfterEvent bool + // Event defines the operation of poll.Control. type Event int diff --git a/internal/poller/poller_epoll.go b/internal/poller/poller_epoll.go index 536819f..8df1984 100644 --- a/internal/poller/poller_epoll.go +++ b/internal/poller/poller_epoll.go @@ -158,6 +158,9 @@ func (ep *epoll) handle(n int) { if inHup { hups = append(hups, desc) } + if GoschedAfterEvent { + runtime.Gosched() + } } if wakeUp { ep.runAsyncTasks() diff --git a/internal/poller/poller_kqueue.go b/internal/poller/poller_kqueue.go index 344eddd..f36f1c8 100644 --- a/internal/poller/poller_kqueue.go +++ b/internal/poller/poller_kqueue.go @@ -125,6 +125,9 @@ func (k *kqueue) handle(n int) { } } } + if GoschedAfterEvent { + runtime.Gosched() + } } if wakeUp { diff --git a/options.go b/options.go index 728a7ac..c16d6c8 100644 --- a/options.go +++ b/options.go @@ -25,6 +25,13 @@ func NumPollers() int { return poller.NumPollers() } +// EnablePollerGoschedAfterEvent enables calling runtime.Gosched() after processing of each event +// during epoll wait handling. +// This function can only be called inside func init(). +func EnablePollerGoschedAfterEvent() { + poller.GoschedAfterEvent = true +} + // OnTCPOpened fires when the tcp connection is established. type OnTCPOpened func(conn Conn) error From 9bd01c55ad479f000bc16c3b01b1180548015b15 Mon Sep 17 00:00:00 2001 From: leoxhyang Date: Thu, 21 Sep 2023 17:39:36 +0800 Subject: [PATCH 14/17] replace writev rawsyscall to syscall (merge request !212) Squash merge branch 'write-syscall' into 'master' Replace writev rawsyscall to syscall. When a user calls Writev, the business goroutine may directly trigger the writev system call during the flush process, which can potentially block. The use of rawsyscall is not allowed in blocking syscall scenario. --- netfd.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netfd.go b/netfd.go index ed27ffa..95d0fdd 100644 --- a/netfd.go +++ b/netfd.go @@ -175,7 +175,7 @@ func (nfd *netFD) Writev(ivs []unix.Iovec) (int, error) { if len(ivs) == 0 { return 0, nil } - r, _, e := unix.RawSyscall(unix.SYS_WRITEV, uintptr(nfd.fd), uintptr(unsafe.Pointer(&ivs[0])), uintptr(len(ivs))) + r, _, e := unix.Syscall(unix.SYS_WRITEV, uintptr(nfd.fd), uintptr(unsafe.Pointer(&ivs[0])), uintptr(len(ivs))) metrics.Add(metrics.TCPWritevCalls, 1) if e != 0 { metrics.Add(metrics.TCPWritevFails, 1) From b339e311643722702f203b6c41dccfd8a0b61556 Mon Sep 17 00:00:00 2001 From: wineguo Date: Fri, 22 Sep 2023 02:39:11 +0000 Subject: [PATCH 15/17] Revert replace writev rawsyscall to syscall (merge request !212) (merge request !213) Squash merge branch 'revert-0040557b' into 'master' This reverts merge request !212 image.png Temporarily revert !212. Needs further investigation. TAPD: --story=887558867 --- netfd.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netfd.go b/netfd.go index 95d0fdd..ed27ffa 100644 --- a/netfd.go +++ b/netfd.go @@ -175,7 +175,7 @@ func (nfd *netFD) Writev(ivs []unix.Iovec) (int, error) { if len(ivs) == 0 { return 0, nil } - r, _, e := unix.Syscall(unix.SYS_WRITEV, uintptr(nfd.fd), uintptr(unsafe.Pointer(&ivs[0])), uintptr(len(ivs))) + r, _, e := unix.RawSyscall(unix.SYS_WRITEV, uintptr(nfd.fd), uintptr(unsafe.Pointer(&ivs[0])), uintptr(len(ivs))) metrics.Add(metrics.TCPWritevCalls, 1) if e != 0 { metrics.Add(metrics.TCPWritevFails, 1) From c83a63b7c1f090d6bc7a880930604ab6f3317c89 Mon Sep 17 00:00:00 2001 From: wineguo Date: Wed, 11 Oct 2023 16:23:15 +0800 Subject: [PATCH 16/17] event: add package comments --- internal/poller/event/defs_linux_386.go | 1 + internal/poller/event/defs_linux_amd64.go | 1 + internal/poller/event/defs_linux_arm.go | 1 + internal/poller/event/defs_linux_arm64.go | 1 + internal/poller/event/defs_linux_loong64.go | 1 + internal/poller/event/defs_linux_mips64x.go | 1 + internal/poller/event/defs_linux_mipsx.go | 1 + internal/poller/event/defs_linux_ppc64x.go | 1 + internal/poller/event/defs_linux_riscv64.go | 1 + internal/poller/event/defs_linux_s390x.go | 1 + 10 files changed, 10 insertions(+) diff --git a/internal/poller/event/defs_linux_386.go b/internal/poller/event/defs_linux_386.go index 1056365..975b417 100644 --- a/internal/poller/event/defs_linux_386.go +++ b/internal/poller/event/defs_linux_386.go @@ -5,6 +5,7 @@ // This file may have been modified by THL A29 Limited ("Tencent Modifications"). // All Tencent Modifications are Copyright (C) 2023 THL A29 Limited. +// Package event provides definitions of event data. package event // EpollEvent defines epoll event data. diff --git a/internal/poller/event/defs_linux_amd64.go b/internal/poller/event/defs_linux_amd64.go index 2359873..e91b18e 100644 --- a/internal/poller/event/defs_linux_amd64.go +++ b/internal/poller/event/defs_linux_amd64.go @@ -5,6 +5,7 @@ // This file may have been modified by THL A29 Limited ("Tencent Modifications"). // All Tencent Modifications are Copyright (C) 2023 THL A29 Limited. +// Package event provides definitions of event data. package event // EpollEvent defines epoll event data. diff --git a/internal/poller/event/defs_linux_arm.go b/internal/poller/event/defs_linux_arm.go index 1d0b52d..1e3abd0 100644 --- a/internal/poller/event/defs_linux_arm.go +++ b/internal/poller/event/defs_linux_arm.go @@ -5,6 +5,7 @@ // This file may have been modified by THL A29 Limited ("Tencent Modifications"). // All Tencent Modifications are Copyright (C) 2023 THL A29 Limited. +// Package event provides definitions of event data. package event // EpollEvent defines epoll event data. diff --git a/internal/poller/event/defs_linux_arm64.go b/internal/poller/event/defs_linux_arm64.go index 1d0b52d..1e3abd0 100644 --- a/internal/poller/event/defs_linux_arm64.go +++ b/internal/poller/event/defs_linux_arm64.go @@ -5,6 +5,7 @@ // This file may have been modified by THL A29 Limited ("Tencent Modifications"). // All Tencent Modifications are Copyright (C) 2023 THL A29 Limited. +// Package event provides definitions of event data. package event // EpollEvent defines epoll event data. diff --git a/internal/poller/event/defs_linux_loong64.go b/internal/poller/event/defs_linux_loong64.go index de57a65..cfada79 100644 --- a/internal/poller/event/defs_linux_loong64.go +++ b/internal/poller/event/defs_linux_loong64.go @@ -5,6 +5,7 @@ // This file may have been modified by THL A29 Limited ("Tencent Modifications"). // All Tencent Modifications are Copyright (C) 2023 THL A29 Limited. +// Package event provides definitions of event data. package event // EpollEvent defines epoll event data. diff --git a/internal/poller/event/defs_linux_mips64x.go b/internal/poller/event/defs_linux_mips64x.go index 7da8ae0..39c47aa 100644 --- a/internal/poller/event/defs_linux_mips64x.go +++ b/internal/poller/event/defs_linux_mips64x.go @@ -7,6 +7,7 @@ //go:build linux && (mips64 || mips64le) +// Package event provides definitions of event data. package event // EpollEvent defines epoll event data. diff --git a/internal/poller/event/defs_linux_mipsx.go b/internal/poller/event/defs_linux_mipsx.go index 1345447..64f90ef 100644 --- a/internal/poller/event/defs_linux_mipsx.go +++ b/internal/poller/event/defs_linux_mipsx.go @@ -7,6 +7,7 @@ //go:build linux && (mips || mipsle) +// Package event provides definitions of event data. package event // EpollEvent defines epoll event data. diff --git a/internal/poller/event/defs_linux_ppc64x.go b/internal/poller/event/defs_linux_ppc64x.go index 8465f3d..c734485 100644 --- a/internal/poller/event/defs_linux_ppc64x.go +++ b/internal/poller/event/defs_linux_ppc64x.go @@ -7,6 +7,7 @@ //go:build linux && (ppc64 || ppc64le) +// Package event provides definitions of event data. package event // EpollEvent defines epoll event data. diff --git a/internal/poller/event/defs_linux_riscv64.go b/internal/poller/event/defs_linux_riscv64.go index de57a65..cfada79 100644 --- a/internal/poller/event/defs_linux_riscv64.go +++ b/internal/poller/event/defs_linux_riscv64.go @@ -5,6 +5,7 @@ // This file may have been modified by THL A29 Limited ("Tencent Modifications"). // All Tencent Modifications are Copyright (C) 2023 THL A29 Limited. +// Package event provides definitions of event data. package event // EpollEvent defines epoll event data. diff --git a/internal/poller/event/defs_linux_s390x.go b/internal/poller/event/defs_linux_s390x.go index de57a65..cfada79 100644 --- a/internal/poller/event/defs_linux_s390x.go +++ b/internal/poller/event/defs_linux_s390x.go @@ -5,6 +5,7 @@ // This file may have been modified by THL A29 Limited ("Tencent Modifications"). // All Tencent Modifications are Copyright (C) 2023 THL A29 Limited. +// Package event provides definitions of event data. package event // EpollEvent defines epoll event data. From 9460676ced5ad758adb6f8cc1ac5c481373882f9 Mon Sep 17 00:00:00 2001 From: wineandchord Date: Wed, 11 Oct 2023 17:20:42 +0800 Subject: [PATCH 17/17] lengthen time --- tcpconn_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tcpconn_test.go b/tcpconn_test.go index b7cc8f6..b4e57c2 100644 --- a/tcpconn_test.go +++ b/tcpconn_test.go @@ -309,7 +309,7 @@ func TestConnWrite_ServHandleErr(t *testing.T) { assert.Nil(t, err) }, ctrlHandle: func(t *testing.T, server tnet.Conn, client net.Conn, ch chan int) { - time.Sleep(time.Millisecond) + time.Sleep(100 * time.Millisecond) assert.Equal(t, false, server.IsActive()) }, isTnetCliConn: true,