mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2025-06-30 22:18:19 -04:00
lock order updates. hard to trigger case in source fallback. The other changes
are for consistency. svn path=/icecast/trunk/icecast/; revision=15619
This commit is contained in:
parent
fd9860ddbf
commit
d49fd42eec
@ -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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
global_unlock();
|
|
||||||
return listener;
|
return listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
*/
|
*/
|
||||||
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)
|
|||||||
|
|
||||||
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");
|
||||||
|
25
src/source.c
25
src/source.c
@ -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)
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
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)
|
|||||||
|
|
||||||
/* 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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
*/
|
*/
|
||||||
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 ();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user