mirror of
https://github.com/yggdrasil-network/yggdrasil-go.git
synced 2024-11-23 10:05:17 +00:00
Tweak lock behaviour
This commit is contained in:
parent
333561f4e1
commit
cb8333f9ff
@ -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
|
||||
|
||||
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,
|
||||
}
|
||||
|
||||
// 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
|
||||
// that are not specific to any given protocol.
|
||||
var options linkOptions
|
||||
@ -196,8 +162,31 @@ func (l *links) add(u *url.URL, sintf string, linkType linkType) error {
|
||||
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()
|
||||
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.Unlock()
|
||||
|
||||
@ -374,17 +363,15 @@ func (l *links) listen(u *url.URL, sintf string) (*Listener, error) {
|
||||
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
|
||||
// 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
|
||||
}
|
||||
|
||||
// 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 {
|
||||
state = &link{
|
||||
linkType: linkTypeIncoming,
|
||||
@ -410,7 +397,6 @@ func (l *links) listen(u *url.URL, sintf string) (*Listener, error) {
|
||||
state.Unlock()
|
||||
|
||||
// Store the state of the link so that it can be queried later.
|
||||
l.Lock()
|
||||
l._links[info] = state
|
||||
l.Unlock()
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user