1
0
mirror of https://github.com/rofafor/vdr-plugin-iptv.git synced 2023-10-10 13:37:03 +02:00

Implement select for I/O

This commit is contained in:
Antti Seppälä 2007-09-13 14:10:37 +00:00
parent 9131cd0e48
commit aa57cc6fa2

View File

@ -3,7 +3,7 @@
* *
* See the README file for copyright information and how to reach the author. * See the README file for copyright information and how to reach the author.
* *
* $Id: streamer.c,v 1.8 2007/09/12 21:55:57 rahrenbe Exp $ * $Id: streamer.c,v 1.9 2007/09/13 14:10:37 ajhseppa Exp $
*/ */
#include <sys/types.h> #include <sys/types.h>
@ -56,17 +56,40 @@ cIptvStreamer::~cIptvStreamer()
void cIptvStreamer::Action() void cIptvStreamer::Action()
{ {
debug("cIptvStreamer::Action(): Entering\n"); debug("cIptvStreamer::Action(): Entering\n");
// Create files necessary for selecting I/O from socket.
fd_set rfds;
FD_ZERO(&rfds);
FD_SET(socketDesc, &rfds);
while (Running()) { while (Running()) {
socklen_t addrlen = sizeof(sa); socklen_t addrlen = sizeof(sa);
int length = recvfrom(socketDesc, pReceiveBuffer, bufferSize, 0,
(struct sockaddr *)&sa, &addrlen); struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 500000;
// Wait for data
int retval = select(socketDesc + 1, &rfds, NULL, NULL, &tv);
if (retval < 0) {
char tmp[64];
error("ERROR: select(): %s", strerror_r(errno, tmp, sizeof(tmp)));
} else if(retval) {
// Read data from socket
int length = recvfrom(socketDesc, pReceiveBuffer, bufferSize,
MSG_DONTWAIT, (struct sockaddr *)&sa, &addrlen);
mutex->Lock(); mutex->Lock();
int p = pRingBuffer->Put(pReceiveBuffer, bufferSize); int p = pRingBuffer->Put(pReceiveBuffer, length);
if (p != length && Running()) { if (p != length && Running()) {
pRingBuffer->ReportOverflow(length - p); pRingBuffer->ReportOverflow(length - p);
debug("Reporting overflow\n");
} }
mutex->Unlock(); mutex->Unlock();
} else {
debug("Timeout waiting for data\n");
}
} }
debug("cIptvStreamer::Action(): Exiting\n"); debug("cIptvStreamer::Action(): Exiting\n");
} }
@ -91,6 +114,14 @@ bool cIptvStreamer::CheckAndCreateSocket(const int port)
return false; return false;
} }
// Make it use non-blocking I/O to avoid stuck read -calls.
if (fcntl(socketDesc, F_SETFL, O_NONBLOCK)) {
char tmp[64];
error("ERROR: fcntl(): %s", strerror_r(errno, tmp, sizeof(tmp)));
close(socketDesc);
return false;
}
int yes = 1; int yes = 1;
// Allow multiple sockets to use the same PORT number // Allow multiple sockets to use the same PORT number
@ -128,6 +159,7 @@ void cIptvStreamer::CloseSocket()
if (socketActive) { if (socketActive) {
close(socketDesc); close(socketDesc);
socketActive = false; socketActive = false;
mcastActive = false;
} }
} }