From e5a6297d30a16682edc52cf66b44b83d19212944 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Mon, 15 Feb 2016 17:26:34 -0500 Subject: [PATCH] Kill TCP sockets in 2 stages to fix a race condition during socket closure --- limelight-common/ControlStream.c | 14 +++++++++----- limelight-common/InputStream.c | 8 ++++++-- limelight-common/PlatformSockets.c | 7 ++++--- limelight-common/PlatformSockets.h | 1 + limelight-common/RtspConnection.c | 6 +++--- 5 files changed, 23 insertions(+), 13 deletions(-) diff --git a/limelight-common/ControlStream.c b/limelight-common/ControlStream.c index 088a418..fc90304 100644 --- a/limelight-common/ControlStream.c +++ b/limelight-common/ControlStream.c @@ -392,19 +392,23 @@ int stopControlStream(void) { LbqSignalQueueShutdown(&invalidReferenceFrameTuples); PltSetEvent(&invalidateRefFramesEvent); + if (ctlSock != INVALID_SOCKET) { + shutdownSocket(ctlSock); + } + PltInterruptThread(&lossStatsThread); PltInterruptThread(&invalidateRefFramesThread); - if (ctlSock != INVALID_SOCKET) { - closeSocket(ctlSock); - ctlSock = INVALID_SOCKET; - } - PltJoinThread(&lossStatsThread); PltJoinThread(&invalidateRefFramesThread); PltCloseThread(&lossStatsThread); PltCloseThread(&invalidateRefFramesThread); + + if (ctlSock != INVALID_SOCKET) { + closeSocket(ctlSock); + ctlSock = INVALID_SOCKET; + } return 0; } diff --git a/limelight-common/InputStream.c b/limelight-common/InputStream.c index e99b2b7..587f590 100644 --- a/limelight-common/InputStream.c +++ b/limelight-common/InputStream.c @@ -294,12 +294,16 @@ int stopInputStream(void) { PltInterruptThread(&inputSendThread); if (inputSock != INVALID_SOCKET) { - closeSocket(inputSock); - inputSock = INVALID_SOCKET; + shutdownSocket(inputSock); } PltJoinThread(&inputSendThread); PltCloseThread(&inputSendThread); + + if (inputSock != INVALID_SOCKET) { + closeSocket(inputSock); + inputSock = INVALID_SOCKET; + } return 0; } diff --git a/limelight-common/PlatformSockets.c b/limelight-common/PlatformSockets.c index 2b6fc87..2678fe8 100644 --- a/limelight-common/PlatformSockets.c +++ b/limelight-common/PlatformSockets.c @@ -21,12 +21,13 @@ void addrToUrlSafeString(struct sockaddr_storage* addr, char* string) } } -void closeSocket(SOCKET s) { +void shutdownSocket(SOCKET s) { // Calling shutdown() prior to close wakes up callers // blocked in connect(), recv(), and friends. shutdown(s, SHUT_RDWR); - - // Now close the socket fd +} + +void closeSocket(SOCKET s) { #ifdef _WIN32 closesocket(s); #else diff --git a/limelight-common/PlatformSockets.h b/limelight-common/PlatformSockets.h index f9fbdb6..0383e7a 100644 --- a/limelight-common/PlatformSockets.h +++ b/limelight-common/PlatformSockets.h @@ -43,4 +43,5 @@ void addrToUrlSafeString(struct sockaddr_storage* addr, char* string); SOCKET connectTcpSocket(struct sockaddr_storage* dstaddr, SOCKADDR_LEN addrlen, unsigned short port); SOCKET bindUdpSocket(int addrfamily, int bufferSize); int enableNoDelay(SOCKET s); +void shutdownSocket(SOCKET s); void closeSocket(SOCKET s); \ No newline at end of file diff --git a/limelight-common/RtspConnection.c b/limelight-common/RtspConnection.c index cbfa1f9..24ddb54 100644 --- a/limelight-common/RtspConnection.c +++ b/limelight-common/RtspConnection.c @@ -144,11 +144,11 @@ Exit: return ret; } -// Terminate the RTSP Handshake process by closing the socket +// Terminate the RTSP Handshake process by shutting down the socket. +// The thread waiting on RTSP will close the socket. void terminateRtspHandshake(void) { if (sock != INVALID_SOCKET) { - closeSocket(sock); - sock = INVALID_SOCKET; + shutdownSocket(sock); } }