From 3783c61e9296e6a88e4f616b4241c077d8aef636 Mon Sep 17 00:00:00 2001 From: Michael Smith Date: Mon, 30 Dec 2002 15:19:46 +0000 Subject: [PATCH] mountpoint fallbacks. untested, and no interface available to configure them. svn path=/trunk/icecast/; revision=4180 --- src/format_mp3.c | 3 +-- src/source.c | 35 +++++++++++++++++++++++++++++++++-- src/source.h | 4 ++++ 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/src/format_mp3.c b/src/format_mp3.c index af19a9aa..c0bb4264 100644 --- a/src/format_mp3.c +++ b/src/format_mp3.c @@ -70,8 +70,6 @@ format_plugin_t *format_mp3_get_plugin(void) return plugin; } -/* TODO: need locking around source_state->metadata!! */ - static int send_metadata(client_t *client, mp3_client_data *client_state, mp3_state *source_state) { @@ -217,6 +215,7 @@ static void format_mp3_send_headers(format_plugin_t *self, int bytes; client->respcode = 200; + /* TODO: This may need to be ICY/1.0 for shoutcast-compatibility? */ bytes = sock_write(client->con->sock, "HTTP/1.0 200 OK\r\n" "Content-Type: %s\r\n", diff --git a/src/source.c b/src/source.c index ce592c05..7c80f6f2 100644 --- a/src/source.c +++ b/src/source.c @@ -94,6 +94,7 @@ int source_free_source(void *key) source_t *source = (source_t *)key; free(source->mount); + free(source->fallback_mount); client_destroy(source->client); avl_tree_free(source->pending_tree, _free_client); avl_tree_free(source->client_tree, _free_client); @@ -107,6 +108,7 @@ int source_free_source(void *key) void *source_main(void *arg) { source_t *source = (source_t *)arg; + source_t *fallback_source; char buffer[4096]; long bytes, sbytes; int ret, timeout; @@ -346,15 +348,44 @@ done: DEBUG0("Source exiting"); + avl_tree_rlock(global.source_tree); + fallback_source = source_find_mount(source->fallback_mount); + avl_tree_unlock(global.source_tree); + /* we need to empty the client and pending trees */ avl_tree_wlock(source->pending_tree); while (avl_get_first(source->pending_tree)) { - avl_delete(source->pending_tree, avl_get_first(source->pending_tree)->key, _free_client); + client_t *client = (client_t *)avl_get_first( + source->pending_tree)->key; + if(fallback_source) { + avl_delete(source->pending_tree, client, _remove_client); + + // TODO: reset client local format data? + avl_tree_wlock(fallback_source->pending_tree); + avl_insert(fallback_source->pending_tree, (void *)client); + avl_tree_unlock(fallback_source->pending_tree); + } + else { + avl_delete(source->pending_tree, client, _free_client); + } } avl_tree_unlock(source->pending_tree); + avl_tree_wlock(source->client_tree); while (avl_get_first(source->client_tree)) { - avl_delete(source->client_tree, avl_get_first(source->client_tree)->key, _free_client); + client_t *client = (client_t *)avl_get_first(source->client_tree)->key; + + if(fallback_source) { + avl_delete(source->client_tree, client, _remove_client); + + // TODO: reset client local format data? + avl_tree_wlock(fallback_source->pending_tree); + avl_insert(fallback_source->pending_tree, (void *)client); + avl_tree_unlock(fallback_source->pending_tree); + } + else { + avl_delete(source->client_tree, client, _free_client); + } } avl_tree_unlock(source->client_tree); diff --git a/src/source.h b/src/source.h index 637c5ed8..a577f3cc 100644 --- a/src/source.h +++ b/src/source.h @@ -10,6 +10,10 @@ typedef struct source_tag http_parser_t *parser; char *mount; + + /* If this source drops, try to move all clients to this fallback */ + char *fallback_mount; + struct _format_plugin_tag *format; avl_tree *client_tree;