Hi,

I've just been working on a new release of dvbstream from CVS,
and was testing out this patch.

Unfortunately it doesn't seem to work for me on DVB-S, where
it hangs in select. I am investigating further : perhaps its awaiting
data on exceptfds instead? I've got a bad satellite connection
(through trees), which is good for testing with :-)

Regards

Alastair



Adrian Bridgett wrote:

Package: dvbstream
Version: 0.5-2

Whilst looking at a kernel memory leak, I found out that dvbstream is
calling poll() ~ 1500 times a second on my machine.

I've attached a patch which replaces poll() with select().  This also
leads to a 15% reduction in CPU usage in my testing.

Adrian
------------------------------------------------------------------------

diff -Naur dvbstream-0.5-orig/CHANGES dvbstream-0.5/CHANGES
--- dvbstream-0.5-orig/CHANGES  2002-05-15 17:39:58.000000000 +0100
+++ dvbstream-0.5/CHANGES       2006-04-01 00:02:05.000000000 +0100
@@ -1,3 +1,14 @@
+v0.5.1 - 31st March 2006:
+-------------------------
+Changed by Adrian Bridgett from poll() to select().
+Saves ~1500 accept() calls/second which translates into approx 15% CPU saving. +
+
+v0.5 - ??
+---------
+Unknown
+
+
V0.4 - 29th October 2001:
-------------------------

diff -Naur dvbstream-0.5-orig/dvbstream.c dvbstream-0.5/dvbstream.c
--- dvbstream-0.5-orig/dvbstream.c      2004-02-11 15:34:21.000000000 +0000
+++ dvbstream-0.5/dvbstream.c   2006-03-31 23:55:47.000000000 +0100
@@ -30,7 +30,7 @@
#include <ctype.h>
#include <sys/ioctl.h>
#include <sys/time.h>
-#include <sys/poll.h>
+#include <sys/select.h>
#include <sys/stat.h>
#include <resolv.h>
#include <fcntl.h>
@@ -174,22 +174,10 @@
  }
}

-void make_nonblock(int f) {
-  int oldflags;
-
-  if ((oldflags=fcntl(f,F_GETFL,0)) < 0) {
-    perror("F_GETFL");
-  }
-  oldflags|=O_NONBLOCK;
-  if (fcntl(f,F_SETFL,oldflags) < 0) {
-    perror("F_SETFL");
-  }
-}
-
typedef enum {STREAM_ON,STREAM_OFF} state_t;


-  int socketIn, ns;
+  int socketIn, ns = -1;
  int pids[MAX_CHANNELS];
  int pestypes[MAX_CHANNELS];
  unsigned char hi_mappids[8192];
@@ -197,7 +185,6 @@
  int fd_sec;
  int fd_frontend;
  int pid,pid2;
-  int connectionOpen;
  int fromlen;
  char hostname[64];
  char in_ch;
@@ -220,33 +207,31 @@
#define TS_SIZE 188
#define IN_SIZE TS_SIZE

+int accept_telnet() {
+  /* Open a new telnet session if a client is trying to connect */
+  if ((ns = accept(socketIn, (struct sockaddr *)&fsin, &fromlen)) < 0) {
+    perror ("server: accept");
+    return -1;
+  }
+
+  printf("Opened connection\n");
+  writes(ns,"220-DVBSTREAM - ");
+  writes(ns,hostname);
+  writes(ns,"\r\nDONE\r\n");
+  return 1;
+}
+
int process_telnet() {
-  char cmd[1024];
-  int cmd_i=0;
+  static char cmd[1024] = "\0";
+  static int cmd_i=0;
  int i;
  char* ch;
  dmx_pes_type_t pestype;
  unsigned long freq=0;
  unsigned long srate=0;

-    /* Open a new telnet session if a client is trying to connect */
-    if (ns==-1) {
-      if ((ns = accept(socketIn, (struct sockaddr *)&fsin, &fromlen)) > 0) {
-        make_nonblock(ns);
- cmd_i=0; - cmd[0]=0;
-        printf("Opened connection\n");
-        writes(ns,"220-DVBSTREAM - ");
-        writes(ns,hostname);
-        writes(ns,"\r\nDONE\r\n");
-        connectionOpen=1;
-      }
-    }
-
-    /* If a telnet session is open, receive and process any input */
-    if (connectionOpen) {
      /* Read in at most a line of text - any ctrl character ends the line */
-      while (read(ns,&in_ch,1)>0) {
+      while (recv(ns,&in_ch,1,MSG_DONTWAIT)>0) {
          if (in_ch < 32) break;
          /* Prevent buffer overflows */
          if (cmd_i < 1024-1) {
@@ -261,7 +246,6 @@
            writes(ns,"DONE\r\n");
            close(ns);
            ns=-1;
- connectionOpen=0; printf("Closed connection\n");
          } else if (strcasecmp(cmd,"STOP")==0) {
            writes(ns,"STOP\n");
@@ -352,7 +336,6 @@
          writes(ns,"DONE\r\n");
        }
      }
-    }
    return(0);
}

@@ -444,7 +427,8 @@
  int fd_dvr;
  int i,j;
  unsigned char buf[MTU];
-  struct pollfd pfds[2];  // DVR device and Telnet connection
+  fd_set select_fds;      // DVR device, telnet socket and connection
+  int num_fds;
  unsigned int secs = 0;
  unsigned long freq=0;
  unsigned long srate=0;
@@ -691,7 +675,6 @@
             f = fopen(pids_map[map_cnt-1].filename, "w+b");
             if (f != NULL) {
               pids_map[map_cnt-1].fd = fileno(f);
-               make_nonblock(pids_map[map_cnt-1].fd);
               fprintf(stderr, "Open file %s\n", pids_map[map_cnt-1].filename);
             } else {
               pids_map[map_cnt-1].fd = -1;
@@ -729,7 +712,7 @@

  if ((output_type==RTP_PS) && (npids!=2)) {
    fprintf(stderr,"ERROR: PS requires exactly two PIDS - video and audio.\n");
-    exit;
+    exit(1);
  }

  if (signal(SIGHUP, SignalHandler) == SIG_IGN) signal(SIGHUP, SIG_IGN);
@@ -823,32 +806,53 @@
    exit(1);
  }

-  make_nonblock(socketIn);
-
  if (listen(socketIn, 1) < 0) {
    perror("server: listen");
    exit(1);
  }

-  connectionOpen=0;
-  ns=-1;
-  pfds[0].fd=fd_dvr;
-  pfds[0].events=POLLIN|POLLPRI;
-  pfds[1].events=POLLIN|POLLPRI;
-
  /* Set up timer */
  //  if (secs > 0) alarm(secs);
  while ( !Interrupted) {
-    /* Poll the open file descriptors */
-    if (ns==-1) {
-        poll(pfds,1,500);
+    // setup select descriptor set
+    // we always wait on DVR device and
+    // either the socket or telnet session
+    // only one session at a time ATM
+    // in fact, process_telnet can only handle one session
+    FD_ZERO(&select_fds);
+    FD_SET(fd_dvr,&select_fds);
+    if (ns == -1) {
+      FD_SET(socketIn,&select_fds);
    } else {
-        pfds[1].fd=ns;  // This can change
-        poll(pfds,2,500);
+      FD_SET(ns,&select_fds);
+    }
+ + num_fds = (socketIn >= ns) ? socketIn : ns;
+    num_fds++;
+    if (select(num_fds, &select_fds, NULL, NULL, NULL) < 0) {
+      if (errno == EINTR) {
+       continue;
+      }
+      perror("server: select");
+      exit(1);
+    }
+ + if (FD_ISSET(socketIn, &select_fds)) {
+      if (ns != -1) {
+       fprintf(stderr,"Multiple telnets not supported");
+      } else {
+        accept_telnet();
+      }
    }

-    process_telnet();  // See if there is an incoming telnet connection
+    if ((ns != -1) && FD_ISSET(ns, &select_fds)) {
+      process_telnet();
+    }

+    if (! FD_ISSET(fd_dvr, &select_fds)) {
+      continue;
+    }
+ if (output_type==RTP_TS) {
      /* Attempt to read 188 bytes from /dev/ost/dvr */
      if ((bytes_read = read(fd_dvr,free_bytes,PACKET_SIZE)) > 0) {



--
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]

Reply via email to