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:
parent
5c504ec3dd
commit
8a91113028
@ -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);
|
||||||
|
@ -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]);
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
15
src/source.c
15
src/source.c
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user