[patch] Reopen dumpfiles on signal
Ken Treis <[email protected]>
| Newsgroups | gmane.comp.audio.icecast.devel |
|---|---|
| Message-ID | <[email protected]> |
I wanted to use the Icecast dumpfile for hourly stream archival, so I added a signal handler to trigger the re-opening of dumpfiles. This lets me rename the dumpfile, signal Icecast, and repeat. Patch is attached. I've never spent any time in the Icecast source before now, so I had a couple of questions/thoughts: 1. Since all I needed was to trigger a re-open, I went with a new signal & handler (SIGUSR1). But this could have been just as easy to attach to the current HUP handler. In fact, it would have probably been easier, since there'd be no need to duplicate the techniques already used to propagate the message (handler sets global flag, client thread sees flag and triggers event). 2. In my event function, I lock the source tree before iterating it. Is that necessary? I used a read lock, since I'm not modifying the tree structure itself... but while iterating, I set a flag in each source to request that the source re-open its dumpfiles. Does that mean I should have used a write lock instead? 3. I implemented the re-open in source.c rather than in the individual format plugins, which may have been naive of me. I'm dealing strictly with MP3 data here, so I can split the file anywhere. Other formats may not take so kindly to arbitrary stream splits. I'd love to see this integrated and would be glad to tweak/retool as necessary. -- Ken Treis Miriam Technologies, Inc. _______________________________________________ Icecast-dev mailing list [email protected] http://lists.xiph.org/mailman/listinfo/icecast-dev
reopen-dumpfiles.diff
(application/octet-stream, 3.9 KB)
Index: src/global.h
===================================================================
--- src/global.h (revision 17873)
+++ src/global.h (working copy)
@@ -34,6 +34,7 @@
int sources;
int clients;
int schedule_config_reread;
+ int schedule_dumpfile_reopen;
avl_tree *source_tree;
/* for locally defined relays */
Index: src/slave.c
===================================================================
--- src/slave.c (revision 17873)
+++ src/slave.c (working copy)
@@ -717,6 +717,13 @@
global . schedule_config_reread = 0;
}
+ if (global . schedule_dumpfile_reopen)
+ {
+ INFO0 ("Reopening dumpfiles");
+ event_dumpfile_reopen(NULL);
+ global . schedule_dumpfile_reopen = 0;
+ }
+
thread_sleep (1000000);
if (slave_running == 0)
break;
Index: src/event.c
===================================================================
--- src/event.c (revision 17873)
+++ src/event.c (working copy)
@@ -71,3 +71,18 @@
}
}
+void event_dumpfile_reopen(void *arg)
+{
+ avl_node *node;
+ source_t *source;
+
+ avl_tree_rlock(global.source_tree);
+ node = avl_get_first(global.source_tree);
+ while (node) {
+ source = (source_t *)node->key;
+ source->reopen_dumpfile = 1;
+ node = avl_get_next(node);
+ }
+ avl_tree_unlock(global.source_tree);
+}
+
Index: src/event.h
===================================================================
--- src/event.h (revision 17873)
+++ src/event.h (working copy)
@@ -17,5 +17,6 @@
#define EVENT_CONFIG_READ 1
void event_config_read(void *nothing);
+void event_dumpfile_reopen(void *nothing);
#endif /* __EVENT_H__ */
Index: src/source.c
===================================================================
--- src/source.c (revision 17873)
+++ src/source.c (working copy)
@@ -279,6 +279,7 @@
free(source->dumpfilename);
source->dumpfilename = NULL;
+ source->reopen_dumpfile = 0;
if (source->intro_file)
{
@@ -714,6 +715,20 @@
}
/* save stream to file */
+ if (source->reopen_dumpfile) {
+ if (source->dumpfile) {
+ fclose(source->dumpfile);
+ source->dumpfile = NULL;
+ }
+ if (source->dumpfilename) {
+ source->dumpfile = fopen(source->dumpfilename, "ab");
+ if (source->dumpfile == NULL) {
+ WARN2("Cannot re-open dump file \"%s\" for appending: %s, disabling.",
+ source->dumpfilename, strerror(errno));
+ }
+ }
+ source->reopen_dumpfile = 0;
+ }
if (source->dumpfile && source->format->write_buf_to_file)
source->format->write_buf_to_file (source, refbuf);
}
Index: src/source.h
===================================================================
--- src/source.h (revision 17873)
+++ src/source.h (working copy)
@@ -48,6 +48,7 @@
char *dumpfilename; /* Name of a file to dump incoming stream to */
FILE *dumpfile;
+ int reopen_dumpfile;
unsigned long peak_listeners;
unsigned long listeners;
Index: src/sighandler.c
===================================================================
--- src/sighandler.c (revision 17873)
+++ src/sighandler.c (working copy)
@@ -31,6 +31,7 @@
#ifndef _WIN32
void _sig_hup(int signo);
+void _sig_usr1(int signo);
void _sig_die(int signo);
void _sig_ignore(int signo);
#endif
@@ -39,6 +40,7 @@
{
#ifndef _WIN32
signal(SIGHUP, _sig_hup);
+ signal(SIGUSR1, _sig_usr1);
signal(SIGINT, _sig_die);
signal(SIGTERM, _sig_die);
signal(SIGPIPE, SIG_IGN);
@@ -59,6 +61,13 @@
signal(SIGHUP, _sig_hup);
}
+void _sig_usr1(int signo)
+{
+ global.schedule_dumpfile_reopen = 1;
+ /* some OSes require us to reattach the signal handler */
+ signal(SIGUSR1, _sig_usr1);
+}
+
void _sig_die(int signo)
{
INFO1("Caught signal %d, shutting down...", signo);