Commit 4efc54f5 authored by Matt Joiner's avatar Matt Joiner

Revert "Do notifications synchronously"

This reverts commit 3dded3dc.
parent e647659b
...@@ -208,6 +208,9 @@ func (s *Swarm) addConn(tc transport.Conn, dir inet.Direction) (*Conn, error) { ...@@ -208,6 +208,9 @@ func (s *Swarm) addConn(tc transport.Conn, dir inet.Direction) (*Conn, error) {
// * The other will be decremented when Conn.start exits. // * The other will be decremented when Conn.start exits.
s.refs.Add(2) s.refs.Add(2)
// Take the notification lock before releasing the conns lock to block
// Disconnect notifications until after the Connect notifications done.
c.notifyLk.Lock()
s.conns.Unlock() s.conns.Unlock()
// We have a connection now. Cancel all other in-progress dials. // We have a connection now. Cancel all other in-progress dials.
...@@ -217,6 +220,7 @@ func (s *Swarm) addConn(tc transport.Conn, dir inet.Direction) (*Conn, error) { ...@@ -217,6 +220,7 @@ func (s *Swarm) addConn(tc transport.Conn, dir inet.Direction) (*Conn, error) {
s.notifyAll(func(f inet.Notifiee) { s.notifyAll(func(f inet.Notifiee) {
f.Connected(s, c) f.Connected(s, c)
}) })
c.notifyLk.Unlock()
c.start() c.start()
...@@ -434,10 +438,18 @@ func (s *Swarm) Backoff() *DialBackoff { ...@@ -434,10 +438,18 @@ func (s *Swarm) Backoff() *DialBackoff {
// notifyAll sends a signal to all Notifiees // notifyAll sends a signal to all Notifiees
func (s *Swarm) notifyAll(notify func(inet.Notifiee)) { func (s *Swarm) notifyAll(notify func(inet.Notifiee)) {
var wg sync.WaitGroup
s.notifs.RLock() s.notifs.RLock()
wg.Add(len(s.notifs.m))
for f := range s.notifs.m { for f := range s.notifs.m {
notify(f) go func(f inet.Notifiee) {
defer wg.Done()
notify(f)
}(f)
} }
wg.Wait()
s.notifs.RUnlock() s.notifs.RUnlock()
} }
......
...@@ -65,10 +65,17 @@ func (c *Conn) doClose() { ...@@ -65,10 +65,17 @@ func (c *Conn) doClose() {
s.Reset() s.Reset()
} }
c.swarm.notifyAll(func(f inet.Notifiee) { // do this in a goroutine to avoid deadlocking if we call close in an open notification.
f.Disconnected(c.swarm, c) go func() {
}) // prevents us from issuing close notifications before finishing the open notifications
c.swarm.refs.Done() // taken in Swarm.addConn c.notifyLk.Lock()
defer c.notifyLk.Unlock()
c.swarm.notifyAll(func(f inet.Notifiee) {
f.Disconnected(c.swarm, c)
})
c.swarm.refs.Done() // taken in Swarm.addConn
}()
} }
func (c *Conn) removeStream(s *Stream) { func (c *Conn) removeStream(s *Stream) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment