Commit d49fd42e authored by Karl Heyes's avatar Karl Heyes

lock order updates. hard to trigger case in source fallback. The other changes

are for consistency.

svn path=/icecast/trunk/icecast/; revision=15619
parent fd9860dd
...@@ -344,9 +344,11 @@ void admin_handle_request(client_t *client, const char *uri) ...@@ -344,9 +344,11 @@ void admin_handle_request(client_t *client, const char *uri)
client_send_400 (client, "missing pass parameter"); client_send_400 (client, "missing pass parameter");
return; return;
} }
global_lock();
config = config_get_config (); config = config_get_config ();
sc_mount = config->shoutcast_mount; sc_mount = config->shoutcast_mount;
listener = config_get_listen_sock (config, client->con); listener = config_get_listen_sock (config, client->con);
if (listener && listener->shoutcast_mount) if (listener && listener->shoutcast_mount)
sc_mount = listener->shoutcast_mount; sc_mount = listener->shoutcast_mount;
...@@ -354,6 +356,7 @@ void admin_handle_request(client_t *client, const char *uri) ...@@ -354,6 +356,7 @@ void admin_handle_request(client_t *client, const char *uri)
httpp_setvar (client->parser, HTTPP_VAR_PROTOCOL, "ICY"); httpp_setvar (client->parser, HTTPP_VAR_PROTOCOL, "ICY");
httpp_setvar (client->parser, HTTPP_VAR_ICYPASSWORD, pass); httpp_setvar (client->parser, HTTPP_VAR_ICYPASSWORD, pass);
config_release_config (); config_release_config ();
global_unlock();
} }
mount = httpp_get_query_param(client->parser, "mount"); mount = httpp_get_query_param(client->parser, "mount");
......
...@@ -1136,7 +1136,6 @@ listener_t *config_get_listen_sock (ice_config_t *config, connection_t *con) ...@@ -1136,7 +1136,6 @@ listener_t *config_get_listen_sock (ice_config_t *config, connection_t *con)
int i = 0; int i = 0;
listener = config->listen_sock; listener = config->listen_sock;
global_lock();
while (listener) while (listener)
{ {
if (i >= global.server_sockets) if (i >= global.server_sockets)
...@@ -1149,7 +1148,6 @@ listener_t *config_get_listen_sock (ice_config_t *config, connection_t *con) ...@@ -1149,7 +1148,6 @@ listener_t *config_get_listen_sock (ice_config_t *config, connection_t *con)
i++; i++;
} }
} }
global_unlock();
return listener; return listener;
} }
...@@ -718,13 +718,13 @@ void connection_accept_loop (void) ...@@ -718,13 +718,13 @@ void connection_accept_loop (void)
thread_sleep (400000); thread_sleep (400000);
continue; continue;
} }
global_unlock();
/* setup client for reading incoming http */ /* setup client for reading incoming http */
client->refbuf->data [PER_CLIENT_REFBUF_SIZE-1] = '\000'; client->refbuf->data [PER_CLIENT_REFBUF_SIZE-1] = '\000';
if (sock_set_blocking (client->con->sock, 0) || sock_set_nodelay (client->con->sock)) if (sock_set_blocking (client->con->sock, 0) || sock_set_nodelay (client->con->sock))
{ {
global_unlock();
WARN0 ("failed to set tcp options on client connection, dropping"); WARN0 ("failed to set tcp options on client connection, dropping");
client_destroy (client); client_destroy (client);
continue; continue;
...@@ -733,6 +733,7 @@ void connection_accept_loop (void) ...@@ -733,6 +733,7 @@ void connection_accept_loop (void)
node = calloc (1, sizeof (client_queue_t)); node = calloc (1, sizeof (client_queue_t));
if (node == NULL) if (node == NULL)
{ {
global_unlock();
client_destroy (client); client_destroy (client);
continue; continue;
} }
...@@ -750,6 +751,7 @@ void connection_accept_loop (void) ...@@ -750,6 +751,7 @@ void connection_accept_loop (void)
if (listener->shoutcast_mount) if (listener->shoutcast_mount)
node->shoutcast_mount = strdup (listener->shoutcast_mount); node->shoutcast_mount = strdup (listener->shoutcast_mount);
} }
global_unlock();
config_release_config(); config_release_config();
_add_request_queue (node); _add_request_queue (node);
...@@ -778,11 +780,12 @@ void connection_accept_loop (void) ...@@ -778,11 +780,12 @@ void connection_accept_loop (void)
*/ */
int connection_complete_source (source_t *source, int response) int connection_complete_source (source_t *source, int response)
{ {
ice_config_t *config = config_get_config(); ice_config_t *config;
global_lock (); global_lock ();
DEBUG1 ("sources count is %d", global.sources); DEBUG1 ("sources count is %d", global.sources);
config = config_get_config();
if (global.sources < config->source_limit) if (global.sources < config->source_limit)
{ {
const char *contenttype; const char *contenttype;
...@@ -797,8 +800,8 @@ int connection_complete_source (source_t *source, int response) ...@@ -797,8 +800,8 @@ int connection_complete_source (source_t *source, int response)
if (format_type == FORMAT_ERROR) if (format_type == FORMAT_ERROR)
{ {
global_unlock();
config_release_config(); config_release_config();
global_unlock();
if (response) if (response)
{ {
client_send_403 (source->client, "Content-type not supported"); client_send_403 (source->client, "Content-type not supported");
......
...@@ -195,7 +195,7 @@ void source_clear_source (source_t *source) ...@@ -195,7 +195,7 @@ void source_clear_source (source_t *source)
{ {
DEBUG1 ("clearing source \"%s\"", source->mount); DEBUG1 ("clearing source \"%s\"", source->mount);
avl_tree_wlock (source->client_tree); avl_tree_wlock (source->pending_tree);
client_destroy(source->client); client_destroy(source->client);
source->client = NULL; source->client = NULL;
source->parser = NULL; source->parser = NULL;
...@@ -216,19 +216,19 @@ void source_clear_source (source_t *source) ...@@ -216,19 +216,19 @@ void source_clear_source (source_t *source)
stats_event_sub (NULL, "listeners", source->listeners); stats_event_sub (NULL, "listeners", source->listeners);
/* lets kick off any clients that are left on here */ /* lets kick off any clients that are left on here */
avl_tree_wlock (source->client_tree);
while (avl_get_first (source->client_tree)) while (avl_get_first (source->client_tree))
{ {
avl_delete (source->client_tree, avl_delete (source->client_tree,
avl_get_first (source->client_tree)->key, _free_client); avl_get_first (source->client_tree)->key, _free_client);
} }
avl_tree_unlock (source->client_tree);
avl_tree_wlock (source->pending_tree);
while (avl_get_first (source->pending_tree)) while (avl_get_first (source->pending_tree))
{ {
avl_delete (source->pending_tree, avl_delete (source->pending_tree,
avl_get_first(source->pending_tree)->key, _free_client); avl_get_first(source->pending_tree)->key, _free_client);
} }
avl_tree_unlock (source->pending_tree);
if (source->format && source->format->free_plugin) if (source->format && source->format->free_plugin)
source->format->free_plugin (source->format); source->format->free_plugin (source->format);
...@@ -274,7 +274,7 @@ void source_clear_source (source_t *source) ...@@ -274,7 +274,7 @@ void source_clear_source (source_t *source)
} }
source->on_demand_req = 0; source->on_demand_req = 0;
avl_tree_unlock (source->client_tree); avl_tree_unlock (source->pending_tree);
} }
...@@ -338,22 +338,23 @@ void source_move_clients (source_t *source, source_t *dest) ...@@ -338,22 +338,23 @@ void source_move_clients (source_t *source, source_t *dest)
/* if the destination is not running then we can't move clients */ /* if the destination is not running then we can't move clients */
avl_tree_wlock (dest->pending_tree);
if (dest->running == 0 && dest->on_demand == 0) if (dest->running == 0 && dest->on_demand == 0)
{ {
WARN1 ("destination mount %s not running, unable to move clients ", dest->mount); WARN1 ("destination mount %s not running, unable to move clients ", dest->mount);
avl_tree_unlock (dest->pending_tree);
thread_mutex_unlock (&move_clients_mutex); thread_mutex_unlock (&move_clients_mutex);
return; return;
} }
avl_tree_wlock (dest->pending_tree);
do do
{ {
client_t *client; client_t *client;
/* we need to move the client and pending trees - we must take the /* we need to move the client and pending trees - we must take the
* locks in this order to avoid deadlocks */ * 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);
avl_tree_wlock (source->client_tree);
if (source->on_demand == 0 && source->format == NULL) if (source->on_demand == 0 && source->format == NULL)
{ {
...@@ -707,6 +708,9 @@ void source_main (source_t *source) ...@@ -707,6 +708,9 @@ void source_main (source_t *source)
if (source->queue_size > source->queue_size_limit) if (source->queue_size > source->queue_size_limit)
remove_from_q = 1; remove_from_q = 1;
/* acquire write lock on pending_tree */
avl_tree_wlock(source->pending_tree);
/* acquire write lock on client_tree */ /* acquire write lock on client_tree */
avl_tree_wlock(source->client_tree); avl_tree_wlock(source->client_tree);
...@@ -727,9 +731,6 @@ void source_main (source_t *source) ...@@ -727,9 +731,6 @@ void source_main (source_t *source)
client_node = avl_get_next(client_node); client_node = avl_get_next(client_node);
} }
/* acquire write lock on pending_tree */
avl_tree_wlock(source->pending_tree);
/** add pending clients **/ /** add pending clients **/
client_node = avl_get_first(source->pending_tree); client_node = avl_get_first(source->pending_tree);
while (client_node) { while (client_node) {
...@@ -1365,10 +1366,12 @@ static void *source_fallback_file (void *arg) ...@@ -1365,10 +1366,12 @@ static void *source_fallback_file (void *arg)
*/ */
void source_recheck_mounts (int update_all) void source_recheck_mounts (int update_all)
{ {
ice_config_t *config = config_get_config(); ice_config_t *config;
mount_proxy *mount = config->mounts; mount_proxy *mount;
avl_tree_rlock (global.source_tree); avl_tree_rlock (global.source_tree);
config = config_get_config();
mount = config->mounts;
if (update_all) if (update_all)
stats_clear_virtual_mounts (); stats_clear_virtual_mounts ();
......
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