Fix UDP thread terminations

This commit is contained in:
Cameron Gutman 2016-02-15 18:46:14 -05:00
parent ceb9504ade
commit 5de8f4c98c
4 changed files with 34 additions and 29 deletions

View File

@ -161,12 +161,16 @@ static void ReceiveThreadProc(void* context) {
} }
} }
packet->size = (int)recv(rtpSocket, &packet->data[0], MAX_PACKET_SIZE, 0); packet->size = recvUdpSocket(rtpSocket, &packet->data[0], MAX_PACKET_SIZE);
if (packet->size <= 0) { if (packet->size < 0) {
Limelog("Audio Receive: recv() failed: %d\n", (int)LastSocketError()); Limelog("Audio Receive: recvUdpSocket() failed: %d\n", (int)LastSocketError());
ListenerCallbacks.connectionTerminated(LastSocketError()); ListenerCallbacks.connectionTerminated(LastSocketError());
break; break;
} }
else if (packet->size == 0) {
// Receive timed out; try again
continue;
}
if (packet->size < sizeof(RTP_PACKET)) { if (packet->size < sizeof(RTP_PACKET)) {
// Runt packet // Runt packet
@ -253,10 +257,6 @@ void stopAudioStream(void) {
PltInterruptThread(&decoderThread); PltInterruptThread(&decoderThread);
} }
if (rtpSocket != INVALID_SOCKET) {
shutdownUdpSocket(rtpSocket);
}
PltJoinThread(&udpPingThread); PltJoinThread(&udpPingThread);
PltJoinThread(&receiveThread); PltJoinThread(&receiveThread);
if ((AudioCallbacks.capabilities & CAPABILITY_DIRECT_SUBMIT) == 0) { if ((AudioCallbacks.capabilities & CAPABILITY_DIRECT_SUBMIT) == 0) {

View File

@ -27,23 +27,26 @@ void shutdownTcpSocket(SOCKET s) {
shutdown(s, SHUT_RDWR); shutdown(s, SHUT_RDWR);
} }
void shutdownUdpSocket(SOCKET s) { int recvUdpSocket(SOCKET s, char* buffer, int size) {
SOCKADDR_LEN len; fd_set readfds;
struct sockaddr_storage addr; int err;
unsigned char buf[1]; struct timeval tv;
// UDP sockets can't be shutdown(), so we'll indicate FD_ZERO(&readfds);
// termination by sending a 0 byte packet to ourselves FD_SET(s, &readfds);
if (getsockname(s, (struct sockaddr*)&addr, &len) < 0) { // Wait up to 500 ms for the socket to be readable
Limelog("getsockname() failed: %d\n", (int)LastSocketError()); tv.tv_sec = 0;
return; tv.tv_usec = 500 * 1000;
err = select((int)(s) + 1, &readfds, NULL, NULL, &tv);
if (err <= 0) {
// Return if an error or timeout occurs
return err;
} }
if (sendto(s, buf, 0, 0, (struct sockaddr*)&addr, len) < 0) { // This won't block since the socket is readable
Limelog("sendto() failed: %d\n", (int)LastSocketError()); return (int)recv(s, buffer, size, 0);
return;
}
} }
void closeSocket(SOCKET s) { void closeSocket(SOCKET s) {

View File

@ -17,6 +17,7 @@ typedef int SOCKADDR_LEN;
#else #else
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/select.h>
#include <netinet/tcp.h> #include <netinet/tcp.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <arpa/inet.h> #include <arpa/inet.h>
@ -43,6 +44,6 @@ void addrToUrlSafeString(struct sockaddr_storage* addr, char* string);
SOCKET connectTcpSocket(struct sockaddr_storage* dstaddr, SOCKADDR_LEN addrlen, unsigned short port); SOCKET connectTcpSocket(struct sockaddr_storage* dstaddr, SOCKADDR_LEN addrlen, unsigned short port);
SOCKET bindUdpSocket(int addrfamily, int bufferSize); SOCKET bindUdpSocket(int addrfamily, int bufferSize);
int enableNoDelay(SOCKET s); int enableNoDelay(SOCKET s);
void shutdownUdpSocket(SOCKET s); int recvUdpSocket(SOCKET s, char* buffer, int size);
void shutdownTcpSocket(SOCKET s); void shutdownTcpSocket(SOCKET s);
void closeSocket(SOCKET s); void closeSocket(SOCKET s);

View File

@ -80,12 +80,16 @@ static void ReceiveThreadProc(void* context) {
} }
} }
err = (int)recv(rtpSocket, buffer, receiveSize, 0); err = recvUdpSocket(rtpSocket, buffer, receiveSize);
if (err <= 0) { if (err < 0) {
Limelog("Video Receive: recv() failed: %d\n", (int)LastSocketError()); Limelog("Video Receive: recvUdpSocket() failed: %d\n", (int)LastSocketError());
ListenerCallbacks.connectionTerminated(LastSocketError()); ListenerCallbacks.connectionTerminated(LastSocketError());
break; break;
} }
else if (err == 0) {
// Receive timed out; try again
continue;
}
memcpy(&buffer[receiveSize], &err, sizeof(int)); memcpy(&buffer[receiveSize], &err, sizeof(int));
@ -161,9 +165,6 @@ void stopVideoStream(void) {
if (firstFrameSocket != INVALID_SOCKET) { if (firstFrameSocket != INVALID_SOCKET) {
shutdownTcpSocket(firstFrameSocket); shutdownTcpSocket(firstFrameSocket);
} }
if (rtpSocket != INVALID_SOCKET) {
shutdownUdpSocket(rtpSocket);
}
PltJoinThread(&udpPingThread); PltJoinThread(&udpPingThread);
PltJoinThread(&receiveThread); PltJoinThread(&receiveThread);