From 07dbf8603aa1ac3c9a3762f5baee0ec45b29655c Mon Sep 17 00:00:00 2001 From: Yuriy Taraday Date: Mon, 5 Feb 2018 01:28:14 +0400 Subject: [PATCH] Drain callback channel when try to deregister it callback() is blocked on sending into channel otherwise. --- rpc.go | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/rpc.go b/rpc.go index bea3317..6e019d0 100644 --- a/rpc.go +++ b/rpc.go @@ -191,10 +191,10 @@ func (l *Libvirt) listen() { func (l *Libvirt) callback(id uint32, res response) { l.cm.Lock() c, ok := l.callbacks[id] - l.cm.Unlock() if ok { c <- res } + l.cm.Unlock() } // route sends incoming packets to their listeners. @@ -281,7 +281,19 @@ func (l *Libvirt) register(id uint32, c chan response) { // deregister destroys a method response callback func (l *Libvirt) deregister(id uint32) { - l.cm.Lock() + lockChan := make(chan bool) + go func() { + l.cm.Lock() + lockChan <- true + }() +Loop: + for { + select { + case _ = <-l.callbacks[id]: + case _ = <-lockChan: + break Loop + } + } close(l.callbacks[id]) delete(l.callbacks, id) l.cm.Unlock()