rename handle, fix potential deadlock

Signed-off-by: Naman Sood <mail@nsood.in>
pull/1131/head
Naman Sood 2021-01-14 16:49:42 -05:00
parent 51dfd5f681
commit 2ca3005d02
2 changed files with 21 additions and 19 deletions

View File

@ -111,16 +111,16 @@ type userspaceEngine struct {
sentActivityAt map[netaddr.IP]*int64 // value is atomic int64 of unixtime sentActivityAt map[netaddr.IP]*int64 // value is atomic int64 of unixtime
destIPActivityFuncs map[netaddr.IP]func() destIPActivityFuncs map[netaddr.IP]func()
mu sync.Mutex // guards following; see lock order comment below mu sync.Mutex // guards following; see lock order comment below
closing bool // Close was called (even if we're still closing) closing bool // Close was called (even if we're still closing)
statusCallback StatusCallback statusCallback StatusCallback
linkChangeCallback func(major bool, newState *interfaces.State) linkChangeCallback func(major bool, newState *interfaces.State)
peerSequence []wgkey.Key peerSequence []wgkey.Key
endpoints []string endpoints []string
pingers map[wgkey.Key]*pinger // legacy pingers for pre-discovery peers pingers map[wgkey.Key]*pinger // legacy pingers for pre-discovery peers
linkState *interfaces.State linkState *interfaces.State
pendOpen map[flowtrack.Tuple]*pendingOpenFlow // see pendopen.go pendOpen map[flowtrack.Tuple]*pendingOpenFlow // see pendopen.go
networkMapCallbacks map[*networkMapCallbackHandle]NetworkMapCallback networkMapCallbacks map[*someHandle]NetworkMapCallback
// Lock ordering: magicsock.Conn.mu, wgLock, then mu. // Lock ordering: magicsock.Conn.mu, wgLock, then mu.
} }
@ -1282,14 +1282,14 @@ func (e *userspaceEngine) AddNetworkMapCallback(cb NetworkMapCallback) func() {
e.mu.Lock() e.mu.Lock()
defer e.mu.Unlock() defer e.mu.Unlock()
if e.networkMapCallbacks == nil { if e.networkMapCallbacks == nil {
e.networkMapCallbacks = make(map[*networkMapCallbackHandle]NetworkMapCallback) e.networkMapCallbacks = make(map[*someHandle]NetworkMapCallback)
} }
handle := new(networkMapCallbackHandle) h := new(someHandle)
e.networkMapCallbacks[handle] = cb e.networkMapCallbacks[h] = cb
return func() { return func() {
e.mu.Lock() e.mu.Lock()
defer e.mu.Unlock() defer e.mu.Unlock()
delete(e.networkMapCallbacks, handle) delete(e.networkMapCallbacks, h)
} }
} }
@ -1312,8 +1312,9 @@ func (e *userspaceEngine) SetDERPMap(dm *tailcfg.DERPMap) {
func (e *userspaceEngine) SetNetworkMap(nm *controlclient.NetworkMap) { func (e *userspaceEngine) SetNetworkMap(nm *controlclient.NetworkMap) {
e.magicConn.SetNetworkMap(nm) e.magicConn.SetNetworkMap(nm)
e.mu.Lock() e.mu.Lock()
defer e.mu.Unlock() callbacks := e.networkMapCallbacks
for _, fn := range e.networkMapCallbacks { e.mu.Unlock()
for _, fn := range callbacks {
fn(nm) fn(nm)
} }
} }

View File

@ -53,9 +53,10 @@ type NetInfoCallback func(*tailcfg.NetInfo)
// into network map updates. // into network map updates.
type NetworkMapCallback func(*controlclient.NetworkMap) type NetworkMapCallback func(*controlclient.NetworkMap)
// networkMapCallbackHandle is a unique key used to keep track // someHandle is allocated so its pointer address acts as a unique
// of callback functions so they can be removed in the future. // map key handle. (It needs to have non-zero size for Go to guarantee
type networkMapCallbackHandle struct{ _ byte } // the pointer is unique.)
type someHandle struct{ _ byte }
// ErrNoChanges is returned by Engine.Reconfig if no changes were made. // ErrNoChanges is returned by Engine.Reconfig if no changes were made.
var ErrNoChanges = errors.New("no changes made to Engine config") var ErrNoChanges = errors.New("no changes made to Engine config")