Given the outcome of #23194, there is currently no way within rust to cleanly terminate a UDP receive loop thread. If shutdown() is not possible, the only other option I see is to expose a recv_from_timeout of some sort on UdpSocket, so that the thread can periodically check whether a message has been sent on a channel, and terminate when such a message is received.
After thinking about this briefly, I suppose it is possible to craft a special UDP packet and send it to the locally bound UDP port, and have the receive thread terminate when it receives that special packet. I don't think this is necessarily a good way to force people to cleanly terminate such a loop, but it is an option right now.