[Redbutton-devel] SF.net SVN: redbutton: [176] redbutton-download/trunk
Brought to you by:
skilvington
|
From: <ski...@us...> - 2007-01-12 14:59:31
|
Revision: 176
http://svn.sourceforge.net/redbutton/?rev=176&view=rev
Author: skilvington
Date: 2007-01-12 06:59:27 -0800 (Fri, 12 Jan 2007)
Log Message:
-----------
allow remote backends to retune (only to services on the current frequency)
Modified Paths:
--------------
redbutton-download/trunk/TODO
redbutton-download/trunk/command.c
redbutton-download/trunk/listen.c
redbutton-download/trunk/module.h
redbutton-download/trunk/table.c
Modified: redbutton-download/trunk/TODO
===================================================================
--- redbutton-download/trunk/TODO 2007-01-11 17:59:20 UTC (rev 175)
+++ redbutton-download/trunk/TODO 2007-01-12 14:59:27 UTC (rev 176)
@@ -1,3 +1,6 @@
+need to kill all existing command connections on retune
+(listen_data->carousel is stale for them)
+
got an "Out of memory" error when doing avstream and video changed size
(start of C4 news)
can't see how avstream can cause an out of memory error
Modified: redbutton-download/trunk/command.c
===================================================================
--- redbutton-download/trunk/command.c 2007-01-11 17:59:20 UTC (rev 175)
+++ redbutton-download/trunk/command.c 2007-01-12 14:59:27 UTC (rev 176)
@@ -8,6 +8,7 @@
#include <stdbool.h>
#include <stdint.h>
#include <fcntl.h>
+#include <signal.h>
#include "command.h"
#include "assoc.h"
@@ -26,6 +27,7 @@
bool cmd_file(struct listen_data *, FILE *, int, char **);
bool cmd_help(struct listen_data *, FILE *, int, char **);
bool cmd_quit(struct listen_data *, FILE *, int, char **);
+bool cmd_retune(struct listen_data *, FILE *, int, char **);
bool cmd_vstream(struct listen_data *, FILE *, int, char **);
static struct
@@ -44,6 +46,7 @@
{ "file", "<ContentReference>", cmd_file, "Retrieve the given file from the carousel" },
{ "help", "", cmd_help, "List available commands" },
{ "quit", "", cmd_quit, "Close the connection" },
+ { "retune", "<ServiceID>", cmd_retune, "Start downloading the carousel from ServiceID" },
{ "vstream", "<ComponentTag>", cmd_vstream, "Stream the given video component tag" },
{ NULL, NULL, NULL, NULL }
};
@@ -504,6 +507,38 @@
}
/*
+ * retune <ServiceID>
+ * stop downloading the current carousel
+ * start downloading the carousel on the given ServiceID
+ */
+
+bool
+cmd_retune(struct listen_data *listen_data, FILE *client, int argc, char *argv[])
+{
+ struct carousel *car = listen_data->carousel;
+ unsigned int service_id;
+ union sigval value;
+
+
+ CHECK_USAGE(2, "retune <ServiceID>");
+
+ service_id = strtoul(argv[1], NULL, 0);
+
+ /* do we need to retune */
+ if(service_id != car->service_id)
+ {
+ /* send a SIGHUP to the main listener process */
+ value.sival_int = service_id;
+ sigqueue(getppid(), SIGHUP, value);
+ }
+
+ SEND_RESPONSE(200, "OK");
+
+ /* need to close the connection as this process now has stale listen_data->carousel */
+ return true;
+}
+
+/*
* help
*/
Modified: redbutton-download/trunk/listen.c
===================================================================
--- redbutton-download/trunk/listen.c 2007-01-11 17:59:20 UTC (rev 175)
+++ redbutton-download/trunk/listen.c 2007-01-12 14:59:27 UTC (rev 176)
@@ -28,9 +28,21 @@
static int get_host_addr(char *, struct in_addr *);
static void handle_connection(struct listen_data *, int, struct sockaddr_in *);
+
static void dead_child(int);
+static void hup_handler(int, siginfo_t *, void *);
/*
+ * we have a main process that listens for commands on the network
+ * each time a new command is received a new process is forked to handle it
+ * the main process also has a child downloading the carousel
+ * to retune, the command processing process sends a SIGHUP to the main process
+ * the siginfo contains the new service_id
+ * this variable is set by the SIGHUP handler from the siginfo, -1 => no retune needed
+ */
+static volatile int retune_id = -1;
+
+/*
* extract the IP addr and port number from a string in one of these forms:
* host:port
* ip-addr:port
@@ -131,6 +143,13 @@
/* fork off a child to download the carousel */
listen_data.carousel = start_downloader(adapter, timeout, service_id, carousel_id);
+ /* catch SIGHUP - tells us to retune */
+ action.sa_sigaction = hup_handler;
+ sigemptyset(&action.sa_mask);
+ action.sa_flags = SA_SIGINFO;
+ if(sigaction(SIGHUP, &action, NULL) < 0)
+ fatal("signal: SIGHUP: %s", strerror(errno));
+
/* listen on the given ip:port */
verbose("Listening on %s:%u", inet_ntoa(listen_addr->sin_addr), ntohs(listen_addr->sin_port));
@@ -151,11 +170,21 @@
/* listen for connections */
while(true)
{
+ /* do we need to retune */
+ if(retune_id != -1)
+ {
+ verbose("Retune to service_id %d", retune_id);
+ /* kill the current downloader process and start a new one */
+ kill(listen_data.carousel->downloader, SIGKILL);
+ listen_data.carousel = start_downloader(adapter, timeout, retune_id, -1);
+ retune_id = -1;
+ }
+ /* listen for a connection */
FD_ZERO(&read_fds);
FD_SET(listen_sock, &read_fds);
if(select(listen_sock + 1, &read_fds, NULL, NULL, NULL) < 0)
{
- /* could have been interupted by SIGCHLD */
+ /* could have been interupted by SIGCHLD or SIGHUP */
if(errno != EINTR)
error("select: %s", strerror(errno));
continue;
@@ -270,6 +299,9 @@
load_carousel(car);
/* parent continues */
+ /* remember the PID of the downloader process so we can kill it on retune */
+ car->downloader = child;
+
return car;
}
@@ -281,3 +313,13 @@
return;
}
+
+static void
+hup_handler(int signo, siginfo_t *info, void *ctx)
+{
+ if(signo == SIGHUP)
+ retune_id = info->si_value.sival_int;
+
+ return;
+}
+
Modified: redbutton-download/trunk/module.h
===================================================================
--- redbutton-download/trunk/module.h 2007-01-11 17:59:20 UTC (rev 175)
+++ redbutton-download/trunk/module.h 2007-01-12 14:59:27 UTC (rev 176)
@@ -26,6 +26,7 @@
#include <stdint.h>
#include <stdbool.h>
#include <limits.h>
+#include <sys/types.h>
#include "dsmcc.h"
#include "assoc.h"
@@ -58,6 +59,7 @@
char demux_device[PATH_MAX]; /* demux device path */
char dvr_device[PATH_MAX]; /* dvr device path */
unsigned int timeout; /* timeout for the DVB devices */
+ pid_t downloader; /* ID of the process downloading the carousel */
uint16_t service_id;
uint32_t carousel_id;
uint16_t boot_pid; /* PID containing DSI */
Modified: redbutton-download/trunk/table.c
===================================================================
--- redbutton-download/trunk/table.c 2007-01-11 17:59:20 UTC (rev 175)
+++ redbutton-download/trunk/table.c 2007-01-12 14:59:27 UTC (rev 176)
@@ -84,12 +84,14 @@
timeout.tv_usec = 0;
do
{
- _buf[0] = 0;
+ _buf[0] = 0xff; /* we never want table ID 0xff */
FD_ZERO(&readfds);
FD_SET(fd_data, &readfds);
if(select(fd_data + 1, &readfds, NULL, NULL, &timeout) < 0)
{
- error("select: %s", strerror(errno));
+ if(errno == EINTR)
+ continue;
+ error("read_table: select: %s", strerror(errno));
close(fd_data);
return NULL;
}
@@ -147,7 +149,7 @@
/* wait for some data to be ready */
if(select(max + 1, &readfds, NULL, NULL, &timeout) < 0)
{
- error("select: %s", strerror(errno));
+ error("read_dsmcc_tables: select: %s", strerror(errno));
return NULL;
}
/* see which fd is ready */
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|