~fnux/yggdrasil-go-coap

92481866bd1713e2c98a02933f472c0f8a28a91c — Jozef Kralik 1 year, 9 months ago d0a8af7
Fix deadlock (#62)

* fix deadlock -> locked mutex was not released on error from newSessionUDPFunc
1 files changed, 20 insertions(+), 13 deletions(-)

M server.go
M server.go => server.go +20 -13
@@ 625,6 625,23 @@ func (srv *Server) closeSessions(err error) {
	}
}

func (srv *Server) getOrCreateUDPSession(connUDP *coapNet.ConnUDP, s *coapNet.ConnUDPContext) (networkSession, error) {
	srv.sessionUDPMapLock.Lock()
	defer srv.sessionUDPMapLock.Unlock()
	session := srv.sessionUDPMap[s.Key()]
	var err error
	if session == nil {
		session, err = srv.newSessionUDPFunc(connUDP, srv, s)
		if err != nil {
			return nil, err
		}
		c := ClientConn{commander: &ClientCommander{session}}
		srv.NotifySessionNewFunc(&c)
		srv.sessionUDPMap[s.Key()] = session
	}
	return session, nil
}

// serveUDP starts a UDP listener for the server.
func (srv *Server) serveUDP(ctx *shutdownContext, connUDP *coapNet.ConnUDP) error {
	if srv.NotifyStartedFunc != nil {


@@ 644,19 661,9 @@ func (srv *Server) serveUDP(ctx *shutdownContext, connUDP *coapNet.ConnUDP) erro
		}
		m = m[:n]

		srv.sessionUDPMapLock.Lock()
		session := srv.sessionUDPMap[s.Key()]
		if session == nil {
			session, err = srv.newSessionUDPFunc(connUDP, srv, s)
			if err != nil {
				return err
			}
			c := ClientConn{commander: &ClientCommander{session}}
			srv.NotifySessionNewFunc(&c)
			srv.sessionUDPMap[s.Key()] = session
			srv.sessionUDPMapLock.Unlock()
		} else {
			srv.sessionUDPMapLock.Unlock()
		session, err := srv.getOrCreateUDPSession(connUDP, s)
		if err != nil {
			return err
		}

		msg, err := ParseDgramMessage(m)