Commit a255c92b authored by Karl Heyes's avatar Karl Heyes

update move clients code, small cleanups in other places

svn path=/trunk/icecast/; revision=5869
parent 99163414
......@@ -84,7 +84,7 @@ typedef struct ice_config_tag
int client_limit;
int source_limit;
long queue_size_limit;
unsigned queue_size_limit;
int threadpool_size;
int client_timeout;
int header_timeout;
......
......@@ -917,10 +917,10 @@ static void _handle_get_request(connection_t *con,
/* Check for any required authentication first */
if(source->authenticator != NULL) {
if(auth_check_client(source, client) != AUTH_OK) {
avl_tree_unlock(global.source_tree);
INFO1("Client attempted to log in to source (\"%s\")with "
"incorrect or missing password", uri);
client_send_401(client);
avl_tree_unlock(global.source_tree);
return;
}
}
......
......@@ -219,6 +219,7 @@ static void start_relay_stream (relay_server *relay)
if (parser)
httpp_destroy (parser);
src->parser = NULL;
source_clear_source (relay->source);
}
......
......@@ -202,6 +202,13 @@ void source_clear_source (source_t *source)
source->parser = NULL;
source->con = NULL;
if (source->dumpfile)
{
INFO1 ("Closing dumpfile for %s", source->mount);
fclose (source->dumpfile);
source->dumpfile = NULL;
}
/* lets kick off any clients that are left on here */
avl_tree_rlock (source->client_tree);
while (avl_get_first (source->client_tree))
......@@ -235,6 +242,7 @@ void source_clear_source (source_t *source)
util_dict_free (source->audio_info);
source->audio_info = NULL;
#endif
source->queue_size_limit = 0;
source->listeners = 0;
source->no_mount = 0;
source->max_listeners = -1;
......@@ -249,10 +257,8 @@ void source_clear_source (source_t *source)
/* Remove the provided source from the global tree and free it */
int source_free_source(void *key)
void source_free_source (source_t *source)
{
source_t *source = key;
DEBUG1 ("freeing source \"%s\"", source->mount);
avl_tree_wlock (global.source_tree);
avl_delete (global.source_tree, source, NULL);
......@@ -264,7 +270,7 @@ int source_free_source(void *key)
free (source->mount);
free (source);
return 1;
return;
}
......@@ -288,58 +294,76 @@ client_t *source_find_client(source_t *source, int id)
return NULL;
}
/* Move clients from source to dest provided dest is running
* and that the stream format is the same.
* 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)
{
client_t *client;
avl_node *node;
/* we don't want the two write locks to deadlock in here */
thread_mutex_lock (&move_clients_mutex);
/* if the destination is not running then we can't move clients */
if (source->format->type != dest->format->type)
{
WARN2 ("stream %s and %s are of different types, ignored", source->mount, dest->mount);
return;
}
if (dest->running == 0)
{
WARN1 ("source %s not running, unable to move clients ", dest->mount);
WARN1 ("destination mount %s not running, unable to move clients ", dest->mount);
thread_mutex_unlock (&move_clients_mutex);
return;
}
/* we don't want the two write locks to deadlock in here */
thread_mutex_lock (&move_clients_mutex);
/* we need to move the client and pending trees */
avl_tree_wlock (dest->pending_tree);
avl_tree_wlock (source->pending_tree);
while (1)
do
{
node = avl_get_first (source->pending_tree);
if (node == NULL)
break;
client = (client_t *)(node->key);
avl_delete (source->pending_tree, client, NULL);
client_t *client;
/* TODO: reset client local format data? */
avl_insert (dest->pending_tree, (void *)client);
}
avl_tree_unlock (source->pending_tree);
/* we need to move the client and pending trees */
avl_tree_wlock (source->pending_tree);
avl_tree_wlock (source->client_tree);
while (1)
{
node = avl_get_first (source->client_tree);
if (node == NULL)
if (source->format == NULL)
{
INFO1 ("source mount %s is not available", source->mount);
break;
}
if (source->format->type != dest->format->type)
{
WARN2 ("stream %s and %s are of different types, ignored", source->mount, dest->mount);
break;
}
client = (client_t *)(node->key);
avl_delete (source->client_tree, client, NULL);
while (1)
{
avl_node *node = avl_get_first (source->pending_tree);
if (node == NULL)
break;
client = (client_t *)(node->key);
avl_delete (source->pending_tree, client, NULL);
/* TODO: reset client local format data? */
avl_insert (dest->pending_tree, (void *)client);
}
source->listeners = 0;
stats_event(source->mount, "listeners", "0");
avl_tree_unlock (source->client_tree);
/* TODO: reset client local format data? */
avl_insert (dest->pending_tree, (void *)client);
}
avl_tree_wlock (source->client_tree);
while (1)
{
avl_node *node = avl_get_first (source->client_tree);
if (node == NULL)
break;
client = (client_t *)(node->key);
avl_delete (source->client_tree, client, NULL);
/* TODO: reset client local format data? */
avl_insert (dest->pending_tree, (void *)client);
}
source->listeners = 0;
stats_event (source->mount, "listeners", "0");
avl_tree_unlock (source->client_tree);
} while (0);
avl_tree_unlock (source->pending_tree);
avl_tree_unlock (dest->pending_tree);
thread_mutex_unlock (&move_clients_mutex);
}
......@@ -486,7 +510,7 @@ static void source_init (source_t *source)
stats_event_inc (NULL, "source_total_connections");
stats_event (source->mount, "listeners", "0");
stats_event (source->mount, "type", source->format->format_description);
sock_set_blocking (source->con->sock, SOCK_NONBLOCK);
DEBUG0("Source creation complete");
......@@ -795,20 +819,17 @@ done:
stats_event_dec(NULL, "sources");
stats_event(source->mount, "listeners", NULL);
/* we don't remove the source from the tree here, it may be a relay and
therefore reserved */
source_clear_source (source);
global_lock();
global.sources--;
global_unlock();
if(source->dumpfile)
fclose(source->dumpfile);
/* release our hold on the lock so the main thread can continue cleaning up */
thread_rwlock_unlock(source->shutdown_rwlock);
/* we don't remove the source from the tree here, it may be a relay and
therefore reserved */
source_clear_source (source);
return;
}
......
......@@ -68,7 +68,7 @@ source_t *source_find_mount(const char *mount);
source_t *source_find_mount_raw(const char *mount);
client_t *source_find_client(source_t *source, int id);
int source_compare_sources(void *arg, void *a, void *b);
int source_free_source(void *key);
void source_free_source(source_t *source);
void source_move_clients (source_t *source, source_t *dest);
int source_remove_client(void *key);
void source_main(source_t *source);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment