From 096cdc1bcd77b908fd0ecb70d4a307692a42823c Mon Sep 17 00:00:00 2001 From: gVisor bot Date: Sat, 25 Jul 2020 17:47:11 +0800 Subject: [PATCH] Fix: protect alive with atomic value (#834) --- adapters/outbound/base.go | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/adapters/outbound/base.go b/adapters/outbound/base.go index 2c380a41..d51a26dd 100644 --- a/adapters/outbound/base.go +++ b/adapters/outbound/base.go @@ -6,6 +6,7 @@ import ( "errors" "net" "net/http" + "sync/atomic" "time" "github.com/Dreamacro/clash/common/queue" @@ -98,11 +99,11 @@ func newPacketConn(pc net.PacketConn, a C.ProxyAdapter) C.PacketConn { type Proxy struct { C.ProxyAdapter history *queue.Queue - alive bool + alive uint32 } func (p *Proxy) Alive() bool { - return p.alive + return atomic.LoadUint32(&p.alive) > 0 } func (p *Proxy) Dial(metadata *C.Metadata) (C.Conn, error) { @@ -114,7 +115,7 @@ func (p *Proxy) Dial(metadata *C.Metadata) (C.Conn, error) { func (p *Proxy) DialContext(ctx context.Context, metadata *C.Metadata) (C.Conn, error) { conn, err := p.ProxyAdapter.DialContext(ctx, metadata) if err != nil { - p.alive = false + atomic.StoreUint32(&p.alive, 0) } return conn, err } @@ -131,7 +132,7 @@ func (p *Proxy) DelayHistory() []C.DelayHistory { // LastDelay return last history record. if proxy is not alive, return the max value of uint16. func (p *Proxy) LastDelay() (delay uint16) { var max uint16 = 0xffff - if !p.alive { + if atomic.LoadUint32(&p.alive) == 0 { return max } @@ -162,7 +163,11 @@ func (p *Proxy) MarshalJSON() ([]byte, error) { // URLTest get the delay for the specified URL func (p *Proxy) URLTest(ctx context.Context, url string) (t uint16, err error) { defer func() { - p.alive = err == nil + if err == nil { + atomic.StoreUint32(&p.alive, 1) + } else { + atomic.StoreUint32(&p.alive, 0) + } record := C.DelayHistory{Time: time.Now()} if err == nil { record.Delay = t @@ -218,5 +223,5 @@ func (p *Proxy) URLTest(ctx context.Context, url string) (t uint16, err error) { } func NewProxy(adapter C.ProxyAdapter) *Proxy { - return &Proxy{adapter, queue.New(10), true} + return &Proxy{adapter, queue.New(10), 1} }