Use regular mutex instead (less type assertions)

This reverts commit 5ba9dadc49.
This commit is contained in:
Neil Alexander 2023-05-20 18:36:44 +01:00
parent 5ba9dadc49
commit e0b39b303f
No known key found for this signature in database
GPG Key ID: A02A2019A2BB0944
2 changed files with 39 additions and 29 deletions

View File

@ -71,9 +71,9 @@ func (c *Core) GetPeers() []PeerInfo {
conns[p.Conn] = p conns[p.Conn] = p
} }
c.links.links.Range(func(key, value any) bool { c.links.RLock()
info := key.(linkInfo) defer c.links.RUnlock()
state := value.(*link) for info, state := range c.links._links {
var peerinfo PeerInfo var peerinfo PeerInfo
var conn net.Conn var conn net.Conn
phony.Block(state, func() { phony.Block(state, func() {
@ -96,8 +96,7 @@ func (c *Core) GetPeers() []PeerInfo {
peerinfo.Priority = p.Priority peerinfo.Priority = p.Priority
} }
peers = append(peers, peerinfo) peers = append(peers, peerinfo)
return true }
})
return peers return peers
} }

View File

@ -29,12 +29,13 @@ const (
) )
type links struct { type links struct {
core *Core core *Core
tcp *linkTCP // TCP interface support tcp *linkTCP // TCP interface support
tls *linkTLS // TLS interface support tls *linkTLS // TLS interface support
unix *linkUNIX // UNIX interface support unix *linkUNIX // UNIX interface support
socks *linkSOCKS // SOCKS interface support socks *linkSOCKS // SOCKS interface support
links sync.Map // map[linkInfo]*link // *link is nil if connection in progress sync.RWMutex // Protects the below
_links map[linkInfo]*link // *link is nil if connection in progress
} }
type linkProtocol interface { type linkProtocol interface {
@ -92,6 +93,7 @@ func (l *links) init(c *Core) error {
l.tls = l.newLinkTLS(l.tcp) l.tls = l.newLinkTLS(l.tcp)
l.unix = l.newLinkUNIX() l.unix = l.newLinkUNIX()
l.socks = l.newLinkSOCKS() l.socks = l.newLinkSOCKS()
l._links = make(map[linkInfo]*link)
var listeners []ListenAddress var listeners []ListenAddress
phony.Block(c, func() { phony.Block(c, func() {
@ -123,11 +125,13 @@ func (l *links) shutdown() {
} }
func (l *links) isConnectedTo(info linkInfo) bool { func (l *links) isConnectedTo(info linkInfo) bool {
li, ok := l.links.Load(info) l.RLock()
if !ok || li == nil { link, ok := l._links[info]
l.RUnlock()
if !ok {
return false return false
} }
return li.(*link)._conn != nil return link._conn != nil
} }
type linkError string type linkError string
@ -147,12 +151,10 @@ func (l *links) add(u *url.URL, sintf string, linkType linkType) error {
sintf: sintf, sintf: sintf,
linkType: linkType, linkType: linkType,
} }
l.RLock()
var state *link state, ok := l._links[info]
if s, ok := l.links.Load(info); ok { l.RUnlock()
state = s.(*link) if ok && state != nil {
}
if state != nil {
select { select {
case state.kick <- struct{}{}: case state.kick <- struct{}{}:
default: default:
@ -196,7 +198,9 @@ func (l *links) add(u *url.URL, sintf string, linkType linkType) error {
// Store the state of the link, try to connect and then run // Store the state of the link, try to connect and then run
// the handler. // the handler.
l.links.Store(info, state) l.Lock()
l._links[info] = state
l.Unlock()
// Track how many consecutive connection failures we have had, // Track how many consecutive connection failures we have had,
// as we will back off exponentially rather than hammering the // as we will back off exponentially rather than hammering the
@ -227,7 +231,11 @@ func (l *links) add(u *url.URL, sintf string, linkType linkType) error {
// then the loop will run endlessly, using backoffs as needed. // then the loop will run endlessly, using backoffs as needed.
// Otherwise the loop will end, cleaning up the link entry. // Otherwise the loop will end, cleaning up the link entry.
go func() { go func() {
l.links.Delete(info) defer func() {
l.Lock()
defer l.Unlock()
delete(l._links, info)
}()
for { for {
conn, err := l.connect(u, info, options) conn, err := l.connect(u, info, options)
if err != nil { if err != nil {
@ -323,11 +331,10 @@ func (l *links) listen(u *url.URL, sintf string) (*Listener, error) {
_ = conn.Close() _ = conn.Close()
continue continue
} }
var state *link l.RLock()
if s, ok := l.links.Load(info); ok { state, ok := l._links[info]
state = s.(*link) l.RUnlock()
} if !ok || state == nil {
if state == nil {
state = &link{ state = &link{
info: info, info: info,
} }
@ -342,7 +349,9 @@ func (l *links) listen(u *url.URL, sintf string) (*Listener, error) {
state._err = nil state._err = nil
state.linkProto = strings.ToUpper(u.Scheme) state.linkProto = strings.ToUpper(u.Scheme)
}) })
l.links.Store(info, state) l.Lock()
l._links[info] = state
l.Unlock()
if err = l.handler(&info, options, lc); err != nil && err != io.EOF { if err = l.handler(&info, options, lc); err != nil && err != io.EOF {
l.core.log.Debugf("Link %s error: %s\n", u.Host, err) l.core.log.Debugf("Link %s error: %s\n", u.Host, err)
} }
@ -352,7 +361,9 @@ func (l *links) listen(u *url.URL, sintf string) (*Listener, error) {
state._errtime = time.Now() state._errtime = time.Now()
} }
}) })
l.links.Delete(info) l.Lock()
delete(l._links, info)
l.Unlock()
} }
}() }()
return li, nil return li, nil