diff --git a/src/connection.c b/src/connection.c index 7ed7e1eb..92559b47 100644 --- a/src/connection.c +++ b/src/connection.c @@ -564,10 +564,9 @@ int connection_complete_source (source_t *source, int response) source->running = 1; mountinfo = config_find_mount (config, source->mount); - if (mountinfo == NULL) - source_update_settings (config, source, mountinfo); - source_recheck_mounts (); + source_update_settings (config, source, mountinfo); config_release_config(); + slave_rebuild_mounts(); source->shutdown_rwlock = &_source_shutdown_rwlock; DEBUG0 ("source is ready to start"); diff --git a/src/event.c b/src/event.c index f69287e8..b1218844 100644 --- a/src/event.c +++ b/src/event.c @@ -63,7 +63,7 @@ void event_config_read(void *arg) yp_recheck_config (config_get_config_unlocked()); config_release_config(); - slave_recheck_mounts(); + slave_recheck_all(); } } diff --git a/src/slave.c b/src/slave.c index 929dd44a..ed1bae5e 100644 --- a/src/slave.c +++ b/src/slave.c @@ -63,7 +63,8 @@ static void *_slave_thread(void *arg); static thread_type *_slave_thread_id; static int slave_running = 0; -static int update_settings = 0; +static volatile int update_settings = 0; +static volatile int update_streams = 0; static volatile unsigned int max_interval = 0; relay_server *relay_free (relay_server *relay) @@ -108,9 +109,10 @@ relay_server *relay_copy (relay_server *r) /* force a recheck of the relays. This will recheck the master server if * a this is a slave. */ -void slave_recheck_mounts (void) +void slave_recheck_all (void) { max_interval = 0; + update_streams = 1; update_settings = 1; } @@ -301,7 +303,6 @@ static void *start_relay_stream (void *arg) relay_server *relay = arg; source_t *src = relay->source; client_t *client; - ice_config_t *config; INFO1("Starting relayed source at mountpoint \"%s\"", relay->localmount); do @@ -324,10 +325,6 @@ static void *start_relay_stream (void *arg) } stats_event_inc(NULL, "source_relay_connections"); stats_event (relay->localmount, "source_ip", client->con->ip); - config = config_get_config(); - stats_event_args (relay->localmount, "listenurl", "http://%s:%d%s", - config->hostname, config->port, relay->localmount); - config_release_config(); source_main (relay->source); @@ -341,6 +338,7 @@ static void *start_relay_stream (void *arg) /* we've finished, now get cleaned up */ relay->cleanup = 1; + slave_rebuild_mounts(); return NULL; } while (0); /* TODO allow looping through multiple servers */ @@ -384,7 +382,13 @@ static void check_relay_stream (relay_server *relay) relay->source = source_reserve (relay->localmount); if (relay->source) { + ice_config_t *config; DEBUG1("Adding relay source at mountpoint \"%s\"", relay->localmount); + config = config_get_config(); + stats_event_args (relay->localmount, "listenurl", "http://%s:%d%s", + config->hostname, config->port, relay->localmount); + config_release_config(); + stats_event (relay->localmount, "listeners", "0"); slave_rebuild_mounts(); } else @@ -547,7 +551,6 @@ static void relay_check_streams (relay_server *to_start, to_free->running = 0; to_free->source->running = 0; thread_join (to_free->thread); - slave_rebuild_mounts(); } else stats_event (to_free->localmount, NULL, NULL); @@ -673,7 +676,10 @@ static void *_slave_thread(void *arg) ice_config_t *config; unsigned int interval = 0; - source_recheck_mounts(); + update_settings = 0; + update_streams = 0; + + source_recheck_mounts (1); while (1) { @@ -723,8 +729,9 @@ static void *_slave_thread(void *arg) if (update_settings) { + source_recheck_mounts (update_streams); update_settings = 0; - source_recheck_mounts(); + update_streams = 0; } } INFO0 ("shutting down current relays"); diff --git a/src/slave.h b/src/slave.h index 67eb1e82..7c8c68df 100644 --- a/src/slave.h +++ b/src/slave.h @@ -35,7 +35,7 @@ typedef struct _relay_server { void slave_initialize(void); void slave_shutdown(void); -void slave_recheck_mounts (void); +void slave_recheck_all (void); void slave_rebuild_mounts (void); relay_server *relay_free (relay_server *relay); diff --git a/src/source.c b/src/source.c index 14494102..ee29c27f 100644 --- a/src/source.c +++ b/src/source.c @@ -424,10 +424,7 @@ void source_move_clients (source_t *source, source_t *dest) /* see if we need to wake up an on-demand relay */ if (dest->running == 0 && dest->on_demand && count) - { dest->on_demand_req = 1; - slave_rebuild_mounts(); - } avl_tree_unlock (dest->pending_tree); thread_mutex_unlock (&move_clients_mutex); @@ -1211,7 +1208,7 @@ void *source_client_thread (void *arg) source_main (source); source_free_source (source); - source_recheck_mounts (); + slave_rebuild_mounts(); return NULL; } @@ -1345,13 +1342,15 @@ static void *source_fallback_file (void *arg) /* rescan the mount list, so that xsl files are updated to show * unconnected but active fallback mountpoints */ -void source_recheck_mounts (void) +void source_recheck_mounts (int update_all) { ice_config_t *config = config_get_config(); mount_proxy *mount = config->mounts; avl_tree_rlock (global.source_tree); + stats_clear_virtual_mounts (); + while (mount) { source_t *source = source_find_mount (mount->mountname); @@ -1359,7 +1358,9 @@ void source_recheck_mounts (void) if (source) { source = source_find_mount_raw (mount->mountname); - if (source) + stats_event_args (mount->mountname, "listenurl", "http://%s:%d%s", + config->hostname, config->port, mount->mountname); + if (source && update_all) { mount_proxy *mountinfo = config_find_mount (config, source->mount); source_update_settings (config, source, mountinfo); diff --git a/src/source.h b/src/source.h index b7b0e2b6..7a526a04 100644 --- a/src/source.h +++ b/src/source.h @@ -91,7 +91,7 @@ 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); -void source_recheck_mounts (void); +void source_recheck_mounts (int update_all); extern mutex_t move_clients_mutex; diff --git a/src/stats.c b/src/stats.c index 3c1e644f..8a1d73b7 100644 --- a/src/stats.c +++ b/src/stats.c @@ -30,6 +30,7 @@ #include "connection.h" +#include "source.h" #include "global.h" #include "refbuf.h" #include "client.h" @@ -1062,3 +1063,32 @@ void stats_get_streamlist (char *buffer, size_t remaining) thread_mutex_unlock (&_stats_mutex); } +/* This removes any source stats from virtual mountpoints, ie mountpoints + * where no source_t exists. This function requires the global sources lock + * to be held before calling. + */ +void stats_clear_virtual_mounts (void) +{ + avl_node *snode; + + thread_mutex_lock (&_stats_mutex); + snode = avl_get_first(_stats.source_tree); + while (snode) + { + stats_source_t *src = (stats_source_t *)snode->key; + source_t *source = source_find_mount_raw (src->source); + + if (source == NULL) + { + /* no source_t is reserved so remove them now */ + snode = avl_get_next (snode); + DEBUG1 ("releasing %s stats", src->source); + avl_delete (_stats.source_tree, src, _free_source_stats); + continue; + } + + snode = avl_get_next (snode); + } + thread_mutex_unlock (&_stats_mutex); +} + diff --git a/src/stats.h b/src/stats.h index 3d897524..d2484e06 100644 --- a/src/stats.h +++ b/src/stats.h @@ -75,6 +75,7 @@ void stats_shutdown(void); stats_t *stats_get_stats(void); void stats_get_streamlist (char *buffer, size_t remaining); +void stats_clear_virtual_mounts (void); void stats_event(const char *source, const char *name, const char *value); void stats_event_args(const char *source, char *name, char *format, ...);