/* This does the actual connection for a relay. A thread is * started off if a connection can be acquired */ int open_relay (relay_server *relay) { source_t *src = relay->source; relay_server_master *master = relay->masters; client_t *client = src->client; do { int ret; if (master->skip) { INFO3 ("skipping %s:%d for %s", master->ip, master->port, relay->localmount); continue; } thread_mutex_unlock (&src->lock); ret = open_relay_connection (client, relay, master); thread_mutex_lock (&src->lock); if (ret < 0) continue; if (connection_complete_source (src) < 0) { WARN1 ("Failed to complete initialisation on %s", relay->localmount); continue; } return 1; } while ((master = master->next) && global.running == ICE_RUNNING); return -1; }
/* This does the actual connection for a relay. A thread is * started off if a connection can be acquired */ int open_relay (relay_server *relay) { source_t *src = relay->source; relay_server_master *master = relay->masters; client_t *client = src->client; do { int ret; if (master->skip) { INFO3 ("skipping %s:%d for %s", master->ip, master->port, relay->localmount); continue; } thread_rwlock_unlock (&src->lock); ret = open_relay_connection (client, relay, master); thread_rwlock_wlock (&src->lock); if (ret < 0) continue; return 1; } while ((master = master->next) && global.running == ICE_RUNNING); return -1; }
/* This does the actual connection for a relay. A thread is * started off if a connection can be acquired */ static void *start_relay_stream (void *arg) { relay_server *relay = arg; source_t *src = relay->source; client_t *client; ICECAST_LOG_INFO("Starting relayed source at mountpoint \"%s\"", relay->localmount); do { client = open_relay_connection (relay); if (client == NULL) continue; src->client = client; src->parser = client->parser; src->con = client->con; if (connection_complete_source (src, 0) < 0) { ICECAST_LOG_INFO("Failed to complete source initialisation"); client_destroy (client); src->client = NULL; continue; } stats_event_inc(NULL, "source_relay_connections"); stats_event (relay->localmount, "source_ip", client->con->ip); source_main (relay->source); if (relay->on_demand == 0) { /* only keep refreshing YP entries for inactive on-demand relays */ yp_remove (relay->localmount); relay->source->yp_public = -1; relay->start = time(NULL) + 10; /* prevent busy looping if failing */ slave_update_all_mounts(); } /* we've finished, now get cleaned up */ relay->cleanup = 1; slave_rebuild_mounts(); return NULL; } while (0); /* TODO allow looping through multiple servers */ if (relay->source->fallback_mount) { source_t *fallback_source; ICECAST_LOG_DEBUG("failed relay, fallback to %s", relay->source->fallback_mount); avl_tree_rlock(global.source_tree); fallback_source = source_find_mount(relay->source->fallback_mount); if (fallback_source != NULL) source_move_clients(relay->source, fallback_source); avl_tree_unlock(global.source_tree); } source_clear_source(relay->source); /* cleanup relay, but prevent this relay from starting up again too soon */ thread_mutex_lock(&_slave_mutex); thread_mutex_lock(&(config_locks()->relay_lock)); relay->source->on_demand = 0; relay->start = time(NULL) + max_interval; relay->cleanup = 1; thread_mutex_unlock(&(config_locks()->relay_lock)); thread_mutex_unlock(&_slave_mutex); return NULL; }