Hello,
I was writting an UDP listener and I faced the problem that the call to DatagramSocket::read always blocks the calling thread until data is received, no matter the value of the parameter blockUntilSpecifiedAmountHasArrived. If data is not received then the calling thread is blocked forever. If using DatagramSocket::read from a thread's "run" method then that thread will have to be killed the hard way.
Specifically, the recv / recvfrom calls at the method readSocket (juce_Socket.cpp) block the execution until data is received.
I solved the problem by configuring a timeout for the socket (I found the solution here: http://forums.codeguru.com/showthread.php?248123).
I modified the method resetSocketOptions in juce_Socket.cpp as follows:
[EDIT: DISCARDED. See the next post for the correct fix] static bool resetSocketOptions (const SocketHandle handle, const bool isDatagram, const bool allowBroadcast) noexcept { const int sndBufSize = 65536; const int rcvBufSize = 65536; const int one = 1; const int tmOut = 100; return handle > 0 && setsockopt (handle, SOL_SOCKET, SO_RCVBUF, (const char*) &rcvBufSize, sizeof (rcvBufSize)) == 0 && setsockopt (handle, SOL_SOCKET, SO_SNDBUF, (const char*)&sndBufSize, sizeof (sndBufSize)) == 0 && (isDatagram ? ((! allowBroadcast) || setsockopt (handle, SOL_SOCKET, SO_BROADCAST, (const char*) &one, sizeof (one)) == 0) && setsockopt (handle, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tmOut, sizeof (tmOut)) == 0 : (setsockopt (handle, IPPROTO_TCP, TCP_NODELAY, (const char*) &one, sizeof (one)) == 0)); }
So when the socket is a datagram socket, it configures a reading timeout of 100 ms. I'm compiling on Windows now, and the fix works for me. I'll have to compile this project for Linux-ARM next week.
I don't know if this is the more convenient method. Another possible solution is to use fcntl for configuring the socket as non-blocking (described here: http://stackoverflow.com/questions/10312535/how-to-unblock-recv-or-recvfrm-function-in-linux-c).
Is there a better fix/workaround for having non-blocking DatagramSocket::read calls? Can be fixed in the JUCE base code?
Thank you!