mirror of
https://github.com/MetaCubeX/mihomo.git
synced 2025-12-19 16:30:07 +08:00
fix: race in close grpc transport
Some checks failed
Test / test (1.20, macos-13) (push) Waiting to run
Test / test (1.20, macos-latest) (push) Waiting to run
Test / test (1.20, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.20, windows-latest) (push) Waiting to run
Test / test (1.21, macos-13) (push) Waiting to run
Test / test (1.21, macos-latest) (push) Waiting to run
Test / test (1.21, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.21, windows-latest) (push) Waiting to run
Test / test (1.22, macos-13) (push) Waiting to run
Test / test (1.22, macos-latest) (push) Waiting to run
Test / test (1.22, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.22, windows-latest) (push) Waiting to run
Test / test (1.23, macos-13) (push) Waiting to run
Test / test (1.23, macos-latest) (push) Waiting to run
Test / test (1.23, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.23, windows-latest) (push) Waiting to run
Test / test (1.24, macos-13) (push) Waiting to run
Test / test (1.24, macos-latest) (push) Waiting to run
Test / test (1.24, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.24, windows-latest) (push) Waiting to run
Test / test (1.20, ubuntu-latest) (push) Failing after 1s
Test / test (1.21, ubuntu-latest) (push) Failing after 2s
Test / test (1.22, ubuntu-latest) (push) Failing after 1s
Test / test (1.23, ubuntu-latest) (push) Failing after 1s
Test / test (1.24, ubuntu-latest) (push) Failing after 1s
Trigger CMFA Update / trigger-CMFA-update (push) Failing after 0s
Some checks failed
Test / test (1.20, macos-13) (push) Waiting to run
Test / test (1.20, macos-latest) (push) Waiting to run
Test / test (1.20, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.20, windows-latest) (push) Waiting to run
Test / test (1.21, macos-13) (push) Waiting to run
Test / test (1.21, macos-latest) (push) Waiting to run
Test / test (1.21, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.21, windows-latest) (push) Waiting to run
Test / test (1.22, macos-13) (push) Waiting to run
Test / test (1.22, macos-latest) (push) Waiting to run
Test / test (1.22, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.22, windows-latest) (push) Waiting to run
Test / test (1.23, macos-13) (push) Waiting to run
Test / test (1.23, macos-latest) (push) Waiting to run
Test / test (1.23, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.23, windows-latest) (push) Waiting to run
Test / test (1.24, macos-13) (push) Waiting to run
Test / test (1.24, macos-latest) (push) Waiting to run
Test / test (1.24, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.24, windows-latest) (push) Waiting to run
Test / test (1.20, ubuntu-latest) (push) Failing after 1s
Test / test (1.21, ubuntu-latest) (push) Failing after 2s
Test / test (1.22, ubuntu-latest) (push) Failing after 1s
Test / test (1.23, ubuntu-latest) (push) Failing after 1s
Test / test (1.24, ubuntu-latest) (push) Failing after 1s
Trigger CMFA Update / trigger-CMFA-update (push) Failing after 0s
This commit is contained in:
parent
257fead538
commit
d5a03901d2
@ -18,7 +18,6 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/metacubex/mihomo/common/atomic"
|
|
||||||
"github.com/metacubex/mihomo/common/buf"
|
"github.com/metacubex/mihomo/common/buf"
|
||||||
"github.com/metacubex/mihomo/common/pool"
|
"github.com/metacubex/mihomo/common/pool"
|
||||||
"github.com/metacubex/mihomo/component/ech"
|
"github.com/metacubex/mihomo/component/ech"
|
||||||
@ -42,16 +41,19 @@ type DialFn = func(ctx context.Context, network, addr string) (net.Conn, error)
|
|||||||
|
|
||||||
type Conn struct {
|
type Conn struct {
|
||||||
initFn func() (io.ReadCloser, netAddr, error)
|
initFn func() (io.ReadCloser, netAddr, error)
|
||||||
writer io.Writer
|
writer io.Writer // writer must not nil
|
||||||
closer io.Closer
|
closer io.Closer
|
||||||
netAddr
|
netAddr
|
||||||
|
|
||||||
|
initOnce sync.Once
|
||||||
|
initErr error
|
||||||
reader io.ReadCloser
|
reader io.ReadCloser
|
||||||
once sync.Once
|
|
||||||
closed atomic.Bool
|
|
||||||
err error
|
|
||||||
remain int
|
|
||||||
br *bufio.Reader
|
br *bufio.Reader
|
||||||
|
remain int
|
||||||
|
|
||||||
|
closeMutex sync.Mutex
|
||||||
|
closed bool
|
||||||
|
|
||||||
// deadlines
|
// deadlines
|
||||||
deadline *time.Timer
|
deadline *time.Timer
|
||||||
}
|
}
|
||||||
@ -65,7 +67,7 @@ type Config struct {
|
|||||||
func (g *Conn) initReader() {
|
func (g *Conn) initReader() {
|
||||||
reader, addr, err := g.initFn()
|
reader, addr, err := g.initFn()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
g.err = err
|
g.initErr = err
|
||||||
if closer, ok := g.writer.(io.Closer); ok {
|
if closer, ok := g.writer.(io.Closer); ok {
|
||||||
closer.Close()
|
closer.Close()
|
||||||
}
|
}
|
||||||
@ -73,17 +75,21 @@ func (g *Conn) initReader() {
|
|||||||
}
|
}
|
||||||
g.netAddr = addr
|
g.netAddr = addr
|
||||||
|
|
||||||
if !g.closed.Load() {
|
g.closeMutex.Lock()
|
||||||
|
defer g.closeMutex.Unlock()
|
||||||
|
if g.closed { // if g.Close() be called between g.initFn(), direct close the initFn returned reader
|
||||||
|
_ = reader.Close()
|
||||||
|
g.initErr = net.ErrClosed
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
g.reader = reader
|
g.reader = reader
|
||||||
g.br = bufio.NewReader(reader)
|
g.br = bufio.NewReader(reader)
|
||||||
} else {
|
|
||||||
reader.Close()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Conn) Init() error {
|
func (g *Conn) Init() error {
|
||||||
g.once.Do(g.initReader)
|
g.initOnce.Do(g.initReader)
|
||||||
return g.err
|
return g.initErr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Conn) Read(b []byte) (n int, err error) {
|
func (g *Conn) Read(b []byte) (n int, err error) {
|
||||||
@ -100,8 +106,6 @@ func (g *Conn) Read(b []byte) (n int, err error) {
|
|||||||
n, err = io.ReadFull(g.br, b[:size])
|
n, err = io.ReadFull(g.br, b[:size])
|
||||||
g.remain -= n
|
g.remain -= n
|
||||||
return
|
return
|
||||||
} else if g.reader == nil {
|
|
||||||
return 0, net.ErrClosed
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0x00 grpclength(uint32) 0x0A uleb128 payload
|
// 0x00 grpclength(uint32) 0x0A uleb128 payload
|
||||||
@ -147,8 +151,8 @@ func (g *Conn) Write(b []byte) (n int, err error) {
|
|||||||
buf.Write(b)
|
buf.Write(b)
|
||||||
|
|
||||||
_, err = g.writer.Write(buf.Bytes())
|
_, err = g.writer.Write(buf.Bytes())
|
||||||
if err == io.ErrClosedPipe && g.err != nil {
|
if err == io.ErrClosedPipe && g.initErr != nil {
|
||||||
err = g.err
|
err = g.initErr
|
||||||
}
|
}
|
||||||
|
|
||||||
if flusher, ok := g.writer.(http.Flusher); ok {
|
if flusher, ok := g.writer.(http.Flusher); ok {
|
||||||
@ -170,8 +174,8 @@ func (g *Conn) WriteBuffer(buffer *buf.Buffer) error {
|
|||||||
binary.PutUvarint(header[6:], uint64(dataLen))
|
binary.PutUvarint(header[6:], uint64(dataLen))
|
||||||
_, err := g.writer.Write(buffer.Bytes())
|
_, err := g.writer.Write(buffer.Bytes())
|
||||||
|
|
||||||
if err == io.ErrClosedPipe && g.err != nil {
|
if err == io.ErrClosedPipe && g.initErr != nil {
|
||||||
err = g.err
|
err = g.initErr
|
||||||
}
|
}
|
||||||
|
|
||||||
if flusher, ok := g.writer.(http.Flusher); ok {
|
if flusher, ok := g.writer.(http.Flusher); ok {
|
||||||
@ -186,7 +190,17 @@ func (g *Conn) FrontHeadroom() int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (g *Conn) Close() error {
|
func (g *Conn) Close() error {
|
||||||
g.closed.Store(true)
|
g.initOnce.Do(func() { // if initReader not called, it should not be run anymore
|
||||||
|
g.initErr = net.ErrClosed
|
||||||
|
})
|
||||||
|
|
||||||
|
g.closeMutex.Lock()
|
||||||
|
defer g.closeMutex.Unlock()
|
||||||
|
if g.closed {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
g.closed = true
|
||||||
|
|
||||||
var errorArr []error
|
var errorArr []error
|
||||||
|
|
||||||
if reader := g.reader; reader != nil {
|
if reader := g.reader; reader != nil {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user