From d92c9758a6df2570a5e77190144d59b9f54e651c Mon Sep 17 00:00:00 2001 From: Philipp Schafft Date: Wed, 30 Sep 2020 17:50:26 +0000 Subject: [PATCH] Feature: Prepare for support to move single clients --- src/admin.c | 2 +- src/slave.c | 2 +- src/source.c | 46 ++++++++++++++++++++++++++++++---------------- src/source.h | 2 +- 4 files changed, 33 insertions(+), 19 deletions(-) diff --git a/src/admin.c b/src/admin.c index 4fa253b7..2523771f 100644 --- a/src/admin.c +++ b/src/admin.c @@ -659,7 +659,7 @@ static void command_move_clients(client_t *client, node = admin_build_rootnode(doc, "iceresponse"); xmlDocSetRootElement(doc, node); - source_move_clients(source, dest); + source_move_clients(source, dest, NULL); snprintf(buf, sizeof(buf), "Clients moved from %s to %s", source->mount, dest_source); diff --git a/src/slave.c b/src/slave.c index 145871fb..662a3485 100644 --- a/src/slave.c +++ b/src/slave.c @@ -467,7 +467,7 @@ static void *start_relay_stream (void *arg) fallback_source = source_find_mount(relay->source->fallback_mount); if (fallback_source != NULL) - source_move_clients(relay->source, fallback_source); + source_move_clients(relay->source, fallback_source, NULL); avl_tree_unlock(global.source_tree); } diff --git a/src/source.c b/src/source.c index 9ac90234..8cf771b4 100644 --- a/src/source.c +++ b/src/source.c @@ -367,7 +367,7 @@ static inline void source_move_clients__single(source_t *source, avl_tree *from, * The only lock that should be held when this is called is the * source tree lock */ -void source_move_clients(source_t *source, source_t *dest) +void source_move_clients(source_t *source, source_t *dest, connection_id_t *id) { unsigned long count = 0; if (strcmp(source->mount, dest->mount) == 0) { @@ -405,20 +405,34 @@ void source_move_clients(source_t *source, source_t *dest) } } - while (1) { - avl_node *node = avl_get_first(source->pending_tree); - if (node == NULL) - break; - source_move_clients__single(source, source->pending_tree, dest->pending_tree, node); - count++; - } + if (id) { + client_t fakeclient; + connection_t fakecon; + void *result; - while (1) { - avl_node *node = avl_get_first(source->client_tree); - if (node == NULL) - break; - source_move_clients__single(source, source->client_tree, dest->pending_tree, node); - count++; + fakeclient.con = &fakecon; + fakeclient.con->id = *id; + + if (avl_get_by_key(source->client_tree, &fakeclient, &result) == 0) { + source_move_clients__single(source, source->client_tree, dest->pending_tree, result); + count++; + } + } else { + while (1) { + avl_node *node = avl_get_first(source->pending_tree); + if (node == NULL) + break; + source_move_clients__single(source, source->pending_tree, dest->pending_tree, node); + count++; + } + + while (1) { + avl_node *node = avl_get_first(source->client_tree); + if (node == NULL) + break; + source_move_clients__single(source, source->client_tree, dest->pending_tree, node); + count++; + } } ICECAST_LOG_INFO("passing %lu listeners to \"%s\"", count, dest->mount); @@ -653,7 +667,7 @@ static void source_init (source_t *source) fallback_source = source_find_mount(source->fallback_mount); if (fallback_source) - source_move_clients (fallback_source, source); + source_move_clients(fallback_source, source, NULL); avl_tree_unlock(global.source_tree); } @@ -852,7 +866,7 @@ static void source_shutdown (source_t *source) fallback_source = source_find_mount(source->fallback_mount); if (fallback_source != NULL) - source_move_clients(source, fallback_source); + source_move_clients(source, fallback_source, NULL); avl_tree_unlock(global.source_tree); } diff --git a/src/source.h b/src/source.h index 07d4252a..86b9990a 100644 --- a/src/source.h +++ b/src/source.h @@ -95,7 +95,7 @@ source_t *source_find_mount_raw(const char *mount); client_t *source_find_client(source_t *source, connection_id_t id); int source_compare_sources(void *arg, void *a, void *b); void source_free_source(source_t *source); -void source_move_clients (source_t *source, source_t *dest); +void source_move_clients(source_t *source, source_t *dest, connection_id_t *id); int source_remove_client(void *key); void source_main(source_t *source); void source_recheck_mounts (int update_all);