@@ -63,21 +63,99 @@ static volatile int update_all_mounts = 0;
6363static volatile unsigned int max_interval = 0 ;
6464static mutex_t _slave_mutex ; // protects update_settings, update_all_mounts, max_interval
6565
66- master_server * master_free (master_server * master )
66+
67+ /* free a master and return its next master */
68+ master_server * master_free (master_server * master )
6769{
6870 master_server * next = master -> next ;
6971 ICECAST_LOG_DEBUG ("freeing master %s:%d" , master -> server , master -> port );
70- xmlFree (master -> server );
72+ xmlFree (master -> server );
7173 if (master -> username )
72- xmlFree (master -> username );
74+ xmlFree (master -> username );
7375 if (master -> password )
74- xmlFree (master -> password );
76+ xmlFree (master -> password );
7577 if (master -> namespace )
7678 xmlFree (master -> namespace );
77- free (master );
79+ free (master );
7880 return next ;
7981}
8082
83+
84+ /* copy a master and return the copy */
85+ static master_server * master_copy (master_server * master )
86+ {
87+ master_server * copy = calloc (1 , sizeof (* master ));
88+
89+ if (copy )
90+ {
91+ copy -> server = (char * )xmlCharStrdup (master -> server );
92+ if (master -> username )
93+ copy -> username = (char * )xmlCharStrdup (master -> username );
94+ if (master -> password )
95+ copy -> password = (char * )xmlCharStrdup (master -> password );
96+ if (master -> namespace )
97+ copy -> namespace = (char * )xmlCharStrdup (master -> namespace );
98+ copy -> port = master -> port ;
99+ copy -> on_demand = master -> on_demand ;
100+ }
101+ return copy ;
102+ }
103+
104+
105+ /* free master list and return NULL */
106+ static master_server * master_list_free (master_server * list )
107+ {
108+ while ((list = master_free (list )));
109+ return list ;
110+ }
111+
112+
113+ /* insert a master into a master list and return the list head */
114+ static master_server * master_list_insert (master_server * list , master_server * master )
115+ {
116+ master -> next = list ;
117+ return master ;
118+ }
119+
120+
121+ /* copy a master list and return copied list */
122+ static master_server * master_list_copy (master_server * list ) {
123+ master_server * list_copy = NULL ;
124+
125+ while (list )
126+ {
127+ master_server * copy = master_copy (list );
128+ if (copy == NULL )
129+ {
130+ list_copy = master_list_free (list_copy );
131+ break ;
132+ }
133+ list_copy = master_list_insert (list_copy , copy );
134+ list = list -> next ;
135+ }
136+
137+ return list_copy ;
138+ }
139+
140+
141+ /* turn a legacy master (from config) into a master and return it */
142+ static master_server * master_from_legacy (ice_config_t * config ) {
143+ master_server * master = calloc (1 , sizeof (* master ));
144+
145+ if (master ) {
146+ master -> username = strdup (config -> master_username );
147+ if (config -> master_password )
148+ master -> password = strdup (config -> master_password );
149+ if (config -> master_server )
150+ master -> server = strdup (config -> master_server );
151+ master -> port = config -> master_server_port ;
152+ master -> on_demand = config -> on_demand ;
153+ }
154+
155+ return master ;
156+ }
157+
158+
81159relay_server * relay_free (relay_server * relay )
82160{
83161 relay_server * next = relay -> next ;
@@ -719,27 +797,6 @@ static int update_from_master(master_server *master)
719797 return ret ;
720798}
721799
722- static int update_from_master_legacy (ice_config_t * config )
723- {
724- master_server * master = calloc (1 , sizeof (master_server ));
725- int ret = 0 ;
726-
727- if (master ) {
728- master -> username = strdup (config -> master_username );
729- if (config -> master_password )
730- master -> password = strdup (config -> master_password );
731- if (config -> master_server )
732- master -> server = strdup (config -> master_server );
733- master -> port = config -> master_server_port ;
734- master -> on_demand = config -> on_demand ;
735- ret = update_from_master (master );
736- master_free (master );
737- }
738-
739- return ret ;
740- }
741-
742-
743800static void * _slave_thread (void * arg )
744801{
745802 ice_config_t * config ;
@@ -780,27 +837,42 @@ static void *_slave_thread(void *arg)
780837 thread_mutex_lock (& _slave_mutex );
781838 if (max_interval <= interval )
782839 {
783- master_server * master ;
840+ master_server * list = NULL ;
841+
784842 ICECAST_LOG_DEBUG ("checking master stream list" );
785- config = config_get_config ();
786843
787844 if (max_interval == 0 )
788845 skip_timer = 1 ;
789846 interval = 0 ;
847+
848+ config = config_get_config ();
790849 max_interval = config -> master_update_interval ;
850+ config_release_config ();
851+
791852 thread_mutex_unlock (& _slave_mutex );
792853
793- /* update all non-legacy master servers. the config lock is being
794- * held for the entire update process. consider making a copy of
795- * the master linked list and releasing the lock */
796- master = config -> master ;
797- while (master ) {
798- update_from_master (master );
799- master = master -> next ;
854+ /* copy master list and insert legacy master from config. note:
855+ * keeping a global list of master servers that only changes on a
856+ * config change would be much more efficient than performing a
857+ * copy each time we do an update -- implement this (and the
858+ * locking that goes with along with this approach) */
859+ config = config_get_config ();
860+ list = master_list_insert (
861+ master_list_copy (config -> master ),
862+ master_from_legacy (config )
863+ );
864+ config_release_config ();
865+
866+ /* update all master servers */
867+ while (list ) {
868+ update_from_master (list );
869+ list = list -> next ;
800870 }
801871
802- /* update legacy master server */
803- update_from_master_legacy (config );
872+ if (list )
873+ master_list_free (list );
874+
875+ config = config_get_config ();
804876
805877 thread_mutex_lock (& (config_locks ()-> relay_lock ));
806878
0 commit comments