go-qemu icon indicating copy to clipboard operation
go-qemu copied to clipboard

avoid listener goroutine stuck forever on send of error

Open eriknordmark opened this issue 4 years ago • 0 comments

Using the example pattern of monitor.Connect() defer monitor.Disconnect() cmd := []byte({ "execute": "query-status" }) raw, _ := monitor.Run(cmd)

even after the Disconnect() has successfully completed and waiting for 10 seconds there is a goroutine stuck forever at goroutine 20 [chan send]: github.com/digitalocean/go-qemu/qmp.(*SocketMonitor).listen(0xc00037e300, 0x1c8a020, 0xc00000e070, 0xc000100900, 0xc000100960) /pillar/vendor/github.com/digitalocean/go-qemu/qmp/socket.go:188 +0x30e created by github.com/digitalocean/go-qemu/qmp.(*SocketMonitor).Connect /pillar/vendor/github.com/digitalocean/go-qemu/qmp/socket.go:141 +0x325

That is due to an error as a result of the DIsconnect closing the socket. The Run function is not expecting an error and the channel is unbuffered.

Every Connect, Run, Disconnect results in one more stuck goroutine.

The fix in this PR is to make the send be conditional with a timeout. Another approach could be to make the channel buffered. A third approach could be to use a context, have Disconnect cancel the context, and have the listener look for the cancellation on a new done channel.

But offering the simplest fix in this PR.

Closes issue #171

eriknordmark avatar Feb 10 '21 16:02 eriknordmark