5
0
mirror of https://github.com/cwinfo/yggdrasil-go.git synced 2024-12-23 07:35:39 +00:00

Tweak lock behaviour

This commit is contained in:
Neil Alexander 2023-05-21 00:02:04 +01:00
parent 333561f4e1
commit cb8333f9ff
No known key found for this signature in database
GPG Key ID: A02A2019A2BB0944

View File

@ -121,16 +121,6 @@ func (l *links) shutdown() {
}) })
} }
func (l *links) isConnectedTo(info linkInfo) bool {
l.RLock()
link, ok := l._links[info]
l.RUnlock()
if !ok {
return false
}
return link._conn != nil
}
type linkError string type linkError string
func (e linkError) Error() string { return string(e) } func (e linkError) Error() string { return string(e) }
@ -149,30 +139,6 @@ func (l *links) add(u *url.URL, sintf string, linkType linkType) error {
sintf: sintf, sintf: sintf,
} }
// If we think we're already connected to this peer, load up
// the existing peer state. Try to kick the peer if possible,
// which will cause an immediate connection attempt if it is
// backing off for some reason.
l.RLock()
state, ok := l._links[info]
l.RUnlock()
if ok && state != nil {
select {
case state.kick <- struct{}{}:
default:
}
return ErrLinkAlreadyConfigured
}
// Create the link entry. This will contain the connection
// in progress (if any), any error details and a context that
// lets the link be cancelled later.
state = &link{
linkType: linkType,
linkProto: strings.ToUpper(u.Scheme),
kick: make(chan struct{}),
}
// Collect together the link options, these are global options // Collect together the link options, these are global options
// that are not specific to any given protocol. // that are not specific to any given protocol.
var options linkOptions var options linkOptions
@ -196,8 +162,31 @@ func (l *links) add(u *url.URL, sintf string, linkType linkType) error {
options.priority = uint8(pi) options.priority = uint8(pi)
} }
// Store the state of the link so that it can be queried later. // If we think we're already connected to this peer, load up
// the existing peer state. Try to kick the peer if possible,
// which will cause an immediate connection attempt if it is
// backing off for some reason.
l.Lock() l.Lock()
state, ok := l._links[info]
if ok && state != nil {
select {
case state.kick <- struct{}{}:
default:
}
l.Unlock()
return ErrLinkAlreadyConfigured
}
// Create the link entry. This will contain the connection
// in progress (if any), any error details and a context that
// lets the link be cancelled later.
state = &link{
linkType: linkType,
linkProto: strings.ToUpper(u.Scheme),
kick: make(chan struct{}),
}
// Store the state of the link so that it can be queried later.
l._links[info] = state l._links[info] = state
l.Unlock() l.Unlock()
@ -374,17 +363,15 @@ func (l *links) listen(u *url.URL, sintf string) (*Listener, error) {
sintf: sintf, sintf: sintf,
} }
// If there's an existing link state for this link, get it.
// If this node is already connected to us, just drop the // If this node is already connected to us, just drop the
// connection. This prevents duplicate peerings. // connection. This prevents duplicate peerings.
if l.isConnectedTo(info) { l.Lock()
state, ok := l._links[info]
if ok && state != nil && state._conn != nil {
l.Unlock()
return return
} }
// If there's an existing link state for this link, get it.
// Otherwise just create a new one.
l.RLock()
state, ok := l._links[info]
l.RUnlock()
if !ok || state == nil { if !ok || state == nil {
state = &link{ state = &link{
linkType: linkTypeIncoming, linkType: linkTypeIncoming,
@ -410,7 +397,6 @@ func (l *links) listen(u *url.URL, sintf string) (*Listener, error) {
state.Unlock() state.Unlock()
// Store the state of the link so that it can be queried later. // Store the state of the link so that it can be queried later.
l.Lock()
l._links[info] = state l._links[info] = state
l.Unlock() l.Unlock()