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)
client_send_400 (client, "missing pass parameter");
return;
}
global_lock();
config = config_get_config ();
sc_mount = config->shoutcast_mount;
listener = config_get_listen_sock (config, client->con);
if (listener && listener->shoutcast_mount)
sc_mount = listener->shoutcast_mount;
......@@ -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_ICYPASSWORD, pass);
config_release_config ();
global_unlock();
}
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)
int i = 0;
listener = config->listen_sock;
global_lock();
while (listener)
{
if (i >= global.server_sockets)
......@@ -1149,7 +1148,6 @@ listener_t *config_get_listen_sock (ice_config_t *config, connection_t *con)
i++;
}
}
global_unlock();
return listener;
}
......@@ -718,13 +718,13 @@ void connection_accept_loop (void)
thread_sleep (400000);
continue;
}
global_unlock();
/* setup client for reading incoming http */
client->refbuf->data [PER_CLIENT_REFBUF_SIZE-1] = '\000';
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");
client_destroy (client);
continue;
......@@ -733,6 +733,7 @@ void connection_accept_loop (void)
node = calloc (1, sizeof (client_queue_t));
if (node == NULL)
{
global_unlock();
client_destroy (client);
continue;
}
......@@ -750,6 +751,7 @@ void connection_accept_loop (void)
if (listener->shoutcast_mount)
node->shoutcast_mount = strdup (listener->shoutcast_mount);
}
global_unlock();
config_release_config();
_add_request_queue (node);
......@@ -778,11 +780,12 @@ void connection_accept_loop (void)
*/
int connection_complete_source (source_t *source, int response)
{
ice_config_t *config = config_get_config();
ice_config_t *config;
global_lock ();
DEBUG1 ("sources count is %d", global.sources);
config = config_get_config();
if (global.sources < config->source_limit)
{
const char *contenttype;
......@@ -797,8 +800,8 @@ int connection_complete_source (source_t *source, int response)
if (format_type == FORMAT_ERROR)
{
global_unlock();
config_release_config();
global_unlock();
if (response)
{
client_send_403 (source->client, "Content-type not supported");
......
......@@ -195,7 +195,7 @@ void source_clear_source (source_t *source)
{
DEBUG1 ("clearing source \"%s\"", source->mount);
avl_tree_wlock (source->client_tree);
avl_tree_wlock (source->pending_tree);
client_destroy(source->client);
source->client = NULL;
source->parser = NULL;
......@@ -216,19 +216,19 @@ void source_clear_source (source_t *source)
stats_event_sub (NULL, "listeners", source->listeners);
/* lets kick off any clients that are left on here */
avl_tree_wlock (source->client_tree);
while (avl_get_first (source->client_tree))
{
avl_delete (source->client_tree,
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))
{
avl_delete (source->pending_tree,
avl_get_first(source->pending_tree)->key, _free_client);
}
avl_tree_unlock (source->pending_tree);
if (source->format && source->format->free_plugin)
source->format->free_plugin (source->format);
......@@ -274,7 +274,7 @@ void source_clear_source (source_t *source)
}
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)
/* 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)
{
WARN1 ("destination mount %s not running, unable to move clients ", dest->mount);
avl_tree_unlock (dest->pending_tree);
thread_mutex_unlock (&move_clients_mutex);
return;
}
avl_tree_wlock (dest->pending_tree);
do
{
client_t *client;
/* 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->client_tree);
if (source->on_demand == 0 && source->format == NULL)
{
......@@ -707,6 +708,9 @@ void source_main (source_t *source)
if (source->queue_size > source->queue_size_limit)
remove_from_q = 1;
/* acquire write lock on pending_tree */
avl_tree_wlock(source->pending_tree);
/* acquire write lock on client_tree */
avl_tree_wlock(source->client_tree);
......@@ -727,9 +731,6 @@ void source_main (source_t *source)
client_node = avl_get_next(client_node);
}
/* acquire write lock on pending_tree */
avl_tree_wlock(source->pending_tree);
/** add pending clients **/
client_node = avl_get_first(source->pending_tree);
while (client_node) {
......@@ -1365,10 +1366,12 @@ static void *source_fallback_file (void *arg)
*/
void source_recheck_mounts (int update_all)
{
ice_config_t *config = config_get_config();
mount_proxy *mount = config->mounts;
ice_config_t *config;
mount_proxy *mount;
avl_tree_rlock (global.source_tree);
config = config_get_config();
mount = config->mounts;
if (update_all)
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