It turns that the root cause was the asyncore.loop() needing to have a
timeout set on systems that use select instead of epoll. Huge thanks to
@binarydud for helping with this. It turns out that setting a short
timeout on the thread.join works as well, but it could cause the asyncore
to be orphanded.