1
0
mirror of https://gitlab.xiph.org/xiph/icecast-server.git synced 2024-12-04 14:46:30 -05:00

Feature: Correctly navigate clients between mounts

This commit is contained in:
Philipp Schafft 2020-10-25 09:05:28 +00:00
parent 5c504ec3dd
commit 8a91113028
5 changed files with 24 additions and 12 deletions

View File

@ -936,6 +936,9 @@ static void __add_listener_to_source(source_t *source, client_t *client)
{ {
size_t loop = 10; size_t loop = 10;
if (navigation_history_navigate_to(&(client->history), source->identifier, NAVIGATION_DIRECTION_REPLACE_ALL) != 0)
ICECAST_LOG_ERROR("Can not change history: navigation of client=%p{.con.id=%llu, ...} to source=%p{.mount=%#H, ...} failed", client, (unsigned long long int)client->con->id, source, source->mount);
do { do {
ICECAST_LOG_DEBUG("max on %s is %ld (cur %lu)", source->mount, ICECAST_LOG_DEBUG("max on %s is %ld (cur %lu)", source->mount,
source->max_listeners, source->listeners); source->max_listeners, source->listeners);
@ -954,6 +957,7 @@ static void __add_listener_to_source(source_t *source, client_t *client)
} }
ICECAST_LOG_INFO("stream full, trying %s", next->mount); ICECAST_LOG_INFO("stream full, trying %s", next->mount);
source = next; source = next;
navigation_history_navigate_to(&(client->history), source->identifier, NAVIGATION_DIRECTION_DOWN);
loop--; loop--;
continue; continue;
} }
@ -967,9 +971,6 @@ static void __add_listener_to_source(source_t *source, client_t *client)
client->refbuf->len = PER_CLIENT_REFBUF_SIZE; client->refbuf->len = PER_CLIENT_REFBUF_SIZE;
memset(client->refbuf->data, 0, PER_CLIENT_REFBUF_SIZE); memset(client->refbuf->data, 0, PER_CLIENT_REFBUF_SIZE);
if (navigation_history_navigate_to(&(client->history), source->identifier, NAVIGATION_DIRECTION_REPLACE_ALL) != 0)
ICECAST_LOG_ERROR("Can not change history: navigation of client=%p{.con.id=%llu, ...} to source=%p{.mount=%#H, ...} failed", client, (unsigned long long int)client->con->id, source, source->mount);
/* lets add the client to the active list */ /* lets add the client to the active list */
avl_tree_wlock(source->pending_tree); avl_tree_wlock(source->pending_tree);
avl_insert(source->pending_tree, client); avl_insert(source->pending_tree, client);

View File

@ -90,6 +90,9 @@ static inline int navigation_history_pop(navigation_history_t *history)
static inline int navigation_history_push(navigation_history_t *history, mount_identifier_t *identifier) static inline int navigation_history_push(navigation_history_t *history, mount_identifier_t *identifier)
{ {
if (history->fill > 0 && mount_identifier_compare(history->history[history->fill - 1], identifier) == 0)
return 0;
if (refobject_ref(identifier) != 0) if (refobject_ref(identifier) != 0)
return -1; return -1;
@ -132,6 +135,9 @@ int navigation_history_navigate_to(navigation_history_t *his
if (!history || !identifier) if (!history || !identifier)
return -1; return -1;
if (direction == NAVIGATION_DIRECTION_UP && history->fill < 2)
direction = NAVIGATION_DIRECTION_REPLACE_ALL;
switch (direction) { switch (direction) {
case NAVIGATION_DIRECTION_UP: case NAVIGATION_DIRECTION_UP:
if (history->fill < 2) if (history->fill < 2)
@ -147,6 +153,10 @@ int navigation_history_navigate_to(navigation_history_t *his
if (history->fill == 0) { if (history->fill == 0) {
return navigation_history_push(history, identifier); return navigation_history_push(history, identifier);
} else { } else {
if (history->fill > 1 && mount_identifier_compare(history->history[history->fill - 2], identifier) == 0) {
return navigation_history_pop(history);
}
if (refobject_ref(identifier) != 0) if (refobject_ref(identifier) != 0)
return -1; return -1;
refobject_unref(history->history[history->fill - 1]); refobject_unref(history->history[history->fill - 1]);

View File

@ -469,7 +469,7 @@ static void *start_relay_stream (void *arg)
fallback_source = source_find_mount(relay->source->fallback_mount); fallback_source = source_find_mount(relay->source->fallback_mount);
if (fallback_source != NULL) if (fallback_source != NULL)
source_move_clients(relay->source, fallback_source, NULL); source_move_clients(relay->source, fallback_source, NULL, NAVIGATION_DIRECTION_DOWN);
avl_tree_unlock(global.source_tree); avl_tree_unlock(global.source_tree);
} }

View File

@ -345,7 +345,7 @@ client_t *source_find_client(source_t *source, connection_id_t id)
return NULL; return NULL;
} }
static inline void source_move_clients__single(source_t *source, avl_tree *from, avl_tree *to, client_t *client) { static inline void source_move_clients__single(source_t *source, source_t *dest, avl_tree *from, avl_tree *to, client_t *client, navigation_direction_t direction) {
avl_delete(from, client, NULL); avl_delete(from, client, NULL);
/* when switching a client to a different queue, be wary of the /* when switching a client to a different queue, be wary of the
@ -360,6 +360,7 @@ static inline void source_move_clients__single(source_t *source, avl_tree *from,
} }
avl_insert(to, (void *)client); avl_insert(to, (void *)client);
navigation_history_navigate_to(&(client->history), dest->identifier, direction);
} }
/* Move clients from source to dest provided dest is running /* Move clients from source to dest provided dest is running
@ -367,7 +368,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 * The only lock that should be held when this is called is the
* source tree lock * source tree lock
*/ */
void source_move_clients(source_t *source, source_t *dest, connection_id_t *id) void source_move_clients(source_t *source, source_t *dest, connection_id_t *id, navigation_direction_t direction)
{ {
unsigned long count = 0; unsigned long count = 0;
if (strcmp(source->mount, dest->mount) == 0) { if (strcmp(source->mount, dest->mount) == 0) {
@ -414,7 +415,7 @@ void source_move_clients(source_t *source, source_t *dest, connection_id_t *id)
fakeclient.con->id = *id; fakeclient.con->id = *id;
if (avl_get_by_key(source->client_tree, &fakeclient, &result) == 0) { if (avl_get_by_key(source->client_tree, &fakeclient, &result) == 0) {
source_move_clients__single(source, source->client_tree, dest->pending_tree, result); source_move_clients__single(source, dest, source->client_tree, dest->pending_tree, result, direction);
count++; count++;
} }
} else { } else {
@ -422,7 +423,7 @@ void source_move_clients(source_t *source, source_t *dest, connection_id_t *id)
avl_node *node = avl_get_first(source->pending_tree); avl_node *node = avl_get_first(source->pending_tree);
if (node == NULL) if (node == NULL)
break; break;
source_move_clients__single(source, source->pending_tree, dest->pending_tree, node->key); source_move_clients__single(source, dest, source->pending_tree, dest->pending_tree, node->key, direction);
count++; count++;
} }
@ -430,7 +431,7 @@ void source_move_clients(source_t *source, source_t *dest, connection_id_t *id)
avl_node *node = avl_get_first(source->client_tree); avl_node *node = avl_get_first(source->client_tree);
if (node == NULL) if (node == NULL)
break; break;
source_move_clients__single(source, source->client_tree, dest->pending_tree, node->key); source_move_clients__single(source, dest, source->client_tree, dest->pending_tree, node->key, direction);
count++; count++;
} }
} }
@ -667,7 +668,7 @@ static void source_init (source_t *source)
fallback_source = source_find_mount(source->fallback_mount); fallback_source = source_find_mount(source->fallback_mount);
if (fallback_source) if (fallback_source)
source_move_clients(fallback_source, source, NULL); source_move_clients(fallback_source, source, NULL, NAVIGATION_DIRECTION_UP);
avl_tree_unlock(global.source_tree); avl_tree_unlock(global.source_tree);
} }
@ -866,7 +867,7 @@ static void source_shutdown (source_t *source)
fallback_source = source_find_mount(source->fallback_mount); fallback_source = source_find_mount(source->fallback_mount);
if (fallback_source != NULL) if (fallback_source != NULL)
source_move_clients(source, fallback_source, NULL); source_move_clients(source, fallback_source, NULL, NAVIGATION_DIRECTION_DOWN);
avl_tree_unlock(global.source_tree); avl_tree_unlock(global.source_tree);
} }

View File

@ -97,7 +97,7 @@ source_t *source_find_mount_raw(const char *mount);
client_t *source_find_client(source_t *source, connection_id_t id); client_t *source_find_client(source_t *source, connection_id_t id);
int source_compare_sources(void *arg, void *a, void *b); int source_compare_sources(void *arg, void *a, void *b);
void source_free_source(source_t *source); void source_free_source(source_t *source);
void source_move_clients(source_t *source, source_t *dest, connection_id_t *id); void source_move_clients(source_t *source, source_t *dest, connection_id_t *id, navigation_direction_t direction);
int source_remove_client(void *key); int source_remove_client(void *key);
void source_main(source_t *source); void source_main(source_t *source);
void source_recheck_mounts (int update_all); void source_recheck_mounts (int update_all);