Fix: protect alive with atomic value (#834)

This commit is contained in:
ayanamist 2020-07-25 17:47:11 +08:00 committed by GitHub
parent 33a6579a3a
commit 8f0098092d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -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}
}