Commit 9a78c1b7 authored by Michael Smith's avatar Michael Smith

Fix deadlock when moving clients. Thanks to oddsock for producing a testcase and

backtrace, and karl for fixing my brain

svn path=/icecast/trunk/icecast/; revision=10017
parent 4c657fb8
...@@ -340,7 +340,9 @@ void source_move_clients (source_t *source, source_t *dest) ...@@ -340,7 +340,9 @@ void source_move_clients (source_t *source, source_t *dest)
{ {
client_t *client; client_t *client;
/* we need to move the client and pending trees */ /* we need to move the client and pending trees - we must take the
* locks in this order to avoid deadlocks */
avl_tree_wlock (source->client_tree);
avl_tree_wlock (source->pending_tree); avl_tree_wlock (source->pending_tree);
if (source->on_demand == 0 && source->format == NULL) if (source->on_demand == 0 && source->format == NULL)
...@@ -381,7 +383,6 @@ void source_move_clients (source_t *source, source_t *dest) ...@@ -381,7 +383,6 @@ void source_move_clients (source_t *source, source_t *dest)
count++; count++;
} }
avl_tree_wlock (source->client_tree);
while (1) while (1)
{ {
avl_node *node = avl_get_first (source->client_tree); avl_node *node = avl_get_first (source->client_tree);
...@@ -409,10 +410,12 @@ void source_move_clients (source_t *source, source_t *dest) ...@@ -409,10 +410,12 @@ void source_move_clients (source_t *source, source_t *dest)
source->listeners = 0; source->listeners = 0;
stats_event (source->mount, "listeners", "0"); stats_event (source->mount, "listeners", "0");
avl_tree_unlock (source->client_tree);
} while (0); } while (0);
avl_tree_unlock (source->pending_tree);
avl_tree_unlock (source->client_tree);
/* see if we need to wake up an on-demand relay */ /* see if we need to wake up an on-demand relay */
if (dest->running == 0 && dest->on_demand && count) if (dest->running == 0 && dest->on_demand && count)
{ {
...@@ -420,7 +423,6 @@ void source_move_clients (source_t *source, source_t *dest) ...@@ -420,7 +423,6 @@ void source_move_clients (source_t *source, source_t *dest)
slave_rebuild_mounts(); slave_rebuild_mounts();
} }
avl_tree_unlock (source->pending_tree);
avl_tree_unlock (dest->pending_tree); avl_tree_unlock (dest->pending_tree);
thread_mutex_unlock (&move_clients_mutex); thread_mutex_unlock (&move_clients_mutex);
} }
......
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