Wrap enet_host_service() to hide the logic required to make retransmissions work

This commit is contained in:
Cameron Gutman 2016-04-18 16:27:50 -04:00
parent 33deb0fe1a
commit d5e0950ec6
4 changed files with 29 additions and 6 deletions

View File

@ -301,7 +301,7 @@ static int sendMessageEnet(short ptype, short paylen, const void* payload) {
memcpy(&packet[1], payload, paylen); memcpy(&packet[1], payload, paylen);
// Gen 5+ servers do control protocol over ENet instead of TCP // Gen 5+ servers do control protocol over ENet instead of TCP
while ((err = enet_host_service(client, &event, 0)) > 0) { while ((err = serviceEnetHost(client, &event, 0)) > 0) {
if (event.type == ENET_EVENT_TYPE_RECEIVE) { if (event.type == ENET_EVENT_TYPE_RECEIVE) {
enet_packet_destroy(event.packet); enet_packet_destroy(event.packet);
} }
@ -391,7 +391,7 @@ static int sendMessageAndDiscardReply(short ptype, short paylen, const void* pay
return 0; return 0;
} }
if (enet_host_service(client, &event, CONTROL_STREAM_TIMEOUT_SEC * 1000) <= 0 || if (serviceEnetHost(client, &event, CONTROL_STREAM_TIMEOUT_SEC * 1000) <= 0 ||
event.type != ENET_EVENT_TYPE_RECEIVE) { event.type != ENET_EVENT_TYPE_RECEIVE) {
PltUnlockMutex(&enetMutex); PltUnlockMutex(&enetMutex);
return 0; return 0;
@ -642,7 +642,7 @@ int startControlStream(void) {
} }
// Wait for the connect to complete // Wait for the connect to complete
if (enet_host_service(client, &event, CONTROL_STREAM_TIMEOUT_SEC * 1000) <= 0 || if (serviceEnetHost(client, &event, CONTROL_STREAM_TIMEOUT_SEC * 1000) <= 0 ||
event.type != ENET_EVENT_TYPE_CONNECT) { event.type != ENET_EVENT_TYPE_CONNECT) {
Limelog("RTSP: Failed to connect to UDP port 47999\n"); Limelog("RTSP: Failed to connect to UDP port 47999\n");
enet_peer_reset(peer); enet_peer_reset(peer);

View File

@ -6,6 +6,8 @@
#include "PlatformThreads.h" #include "PlatformThreads.h"
#include "Video.h" #include "Video.h"
#include <enet/enet.h>
// Common globals // Common globals
extern char* RemoteAddrString; extern char* RemoteAddrString;
extern struct sockaddr_storage RemoteAddr; extern struct sockaddr_storage RemoteAddr;
@ -18,6 +20,7 @@ extern AUDIO_RENDERER_CALLBACKS AudioCallbacks;
extern int NegotiatedVideoFormat; extern int NegotiatedVideoFormat;
int isBeforeSignedInt(int numA, int numB, int ambiguousCase); int isBeforeSignedInt(int numA, int numB, int ambiguousCase);
int serviceEnetHost(ENetHost* client, ENetEvent* event, enet_uint32 timeoutMs);
void fixupMissingCallbacks(PDECODER_RENDERER_CALLBACKS* drCallbacks, PAUDIO_RENDERER_CALLBACKS* arCallbacks, void fixupMissingCallbacks(PDECODER_RENDERER_CALLBACKS* drCallbacks, PAUDIO_RENDERER_CALLBACKS* arCallbacks,
PCONNECTION_LISTENER_CALLBACKS* clCallbacks); PCONNECTION_LISTENER_CALLBACKS* clCallbacks);

View File

@ -1,5 +1,25 @@
#include "Limelight-internal.h" #include "Limelight-internal.h"
#define ENET_SERVICE_RETRIES 10
// This function wraps enet_host_service() and hides the fact that it must be called
// multiple times for retransmissions to work correctly. It is meant to be a drop-in
// replacement for enet_host_service().
int serviceEnetHost(ENetHost* client, ENetEvent* event, enet_uint32 timeoutMs) {
int i;
int ret;
// We need to call enet_host_service() multiple times to make sure retransmissions happen
for (i = 0; i < ENET_SERVICE_RETRIES; i++) {
ret = enet_host_service(client, event, timeoutMs / ENET_SERVICE_RETRIES);
if (ret != 0 || timeoutMs == 0) {
break;
}
}
return ret;
}
int isBeforeSignedInt(int numA, int numB, int ambiguousCase) { int isBeforeSignedInt(int numA, int numB, int ambiguousCase) {
// This should be the common case for most callers // This should be the common case for most callers
if (numA == numB) { if (numA == numB) {

View File

@ -141,7 +141,7 @@ static int transactRtspMessageEnet(PRTSP_MESSAGE request, PRTSP_MESSAGE response
} }
// Wait for a reply // Wait for a reply
if (enet_host_service(client, &event, RTSP_TIMEOUT_SEC * 1000) <= 0 || if (serviceEnetHost(client, &event, RTSP_TIMEOUT_SEC * 1000) <= 0 ||
event.type != ENET_EVENT_TYPE_RECEIVE) { event.type != ENET_EVENT_TYPE_RECEIVE) {
Limelog("Failed to receive RTSP reply\n"); Limelog("Failed to receive RTSP reply\n");
ret = 0; ret = 0;
@ -162,7 +162,7 @@ static int transactRtspMessageEnet(PRTSP_MESSAGE request, PRTSP_MESSAGE response
// Wait for the payload if we're expecting some // Wait for the payload if we're expecting some
if (expectingPayload) { if (expectingPayload) {
// The payload comes in a second packet // The payload comes in a second packet
if (enet_host_service(client, &event, RTSP_TIMEOUT_SEC * 1000) <= 0 || if (serviceEnetHost(client, &event, RTSP_TIMEOUT_SEC * 1000) <= 0 ||
event.type != ENET_EVENT_TYPE_RECEIVE) { event.type != ENET_EVENT_TYPE_RECEIVE) {
Limelog("Failed to receive RTSP reply payload\n"); Limelog("Failed to receive RTSP reply payload\n");
ret = 0; ret = 0;
@ -490,7 +490,7 @@ int performRtspHandshake(void) {
} }
// Wait for the connect to complete // Wait for the connect to complete
if (enet_host_service(client, &event, RTSP_TIMEOUT_SEC * 1000) <= 0 || if (serviceEnetHost(client, &event, RTSP_TIMEOUT_SEC * 1000) <= 0 ||
event.type != ENET_EVENT_TYPE_CONNECT) { event.type != ENET_EVENT_TYPE_CONNECT) {
Limelog("RTSP: Failed to connect to UDP port 48010\n"); Limelog("RTSP: Failed to connect to UDP port 48010\n");
enet_peer_reset(peer); enet_peer_reset(peer);