[xiph-commits] r18454 - icecast/trunk/icecast/src

ph3-der-loewe at svn.xiph.org ph3-der-loewe at svn.xiph.org
Tue Jul 17 07:03:37 PDT 2012


Author: ph3-der-loewe
Date: 2012-07-17 07:03:37 -0700 (Tue, 17 Jul 2012)
New Revision: 18454

Modified:
   icecast/trunk/icecast/src/connection.c
   icecast/trunk/icecast/src/sighandler.c
   icecast/trunk/icecast/src/slave.c
   icecast/trunk/icecast/src/source.c
   icecast/trunk/icecast/src/source.h
   icecast/trunk/icecast/src/stats.c
Log:
race condition patch as submitted by lds and remi, slightly motified by me. closes #1810

Modified: icecast/trunk/icecast/src/connection.c
===================================================================
--- icecast/trunk/icecast/src/connection.c	2012-07-17 04:30:49 UTC (rev 18453)
+++ icecast/trunk/icecast/src/connection.c	2012-07-17 14:03:37 UTC (rev 18454)
@@ -105,7 +105,7 @@
     avl_tree *contents;
 } cache_file_contents;
 
-static spin_t _connection_lock;
+static spin_t _connection_lock; // protects _current_id, _con_queue, _con_queue_tail
 static volatile unsigned long _current_id = 0;
 static int _initialized = 0;
 
@@ -568,8 +568,10 @@
  */
 static void _add_connection (client_queue_t *node)
 {
+    thread_spin_lock (&_connection_lock);
     *_con_queue_tail = node;
     _con_queue_tail = (volatile client_queue_t **)&node->next;
+    thread_spin_unlock (&_connection_lock);
 }
 
 
@@ -580,7 +582,8 @@
 {
     client_queue_t *node = NULL;
 
-    /* common case, no new connections so don't bother taking locks */
+    thread_spin_lock (&_connection_lock);
+
     if (_con_queue)
     {
         node = (client_queue_t *)_con_queue;
@@ -589,6 +592,8 @@
             _con_queue_tail = &_con_queue;
         node->next = NULL;
     }
+
+    thread_spin_unlock (&_connection_lock);
     return node;
 }
 

Modified: icecast/trunk/icecast/src/sighandler.c
===================================================================
--- icecast/trunk/icecast/src/sighandler.c	2012-07-17 04:30:49 UTC (rev 18453)
+++ icecast/trunk/icecast/src/sighandler.c	2012-07-17 14:03:37 UTC (rev 18454)
@@ -54,7 +54,10 @@
 
 void _sig_hup(int signo)
 {
+    global_lock();
     global . schedule_config_reread = 1;
+    global_unlock();
+
     /* some OSes require us to reattach the signal handler */
     signal(SIGHUP, _sig_hup);
 }

Modified: icecast/trunk/icecast/src/slave.c
===================================================================
--- icecast/trunk/icecast/src/slave.c	2012-07-17 04:30:49 UTC (rev 18453)
+++ icecast/trunk/icecast/src/slave.c	2012-07-17 14:03:37 UTC (rev 18454)
@@ -64,6 +64,7 @@
 static volatile int update_settings = 0;
 static volatile int update_all_mounts = 0;
 static volatile unsigned int max_interval = 0;
+static mutex_t _slave_mutex; // protects update_settings, update_all_mounts, max_interval
 
 relay_server *relay_free (relay_server *relay)
 {
@@ -109,9 +110,11 @@
  */
 void slave_update_all_mounts (void)
 {
+    thread_mutex_lock(&_slave_mutex);
     max_interval = 0;
     update_all_mounts = 1;
     update_settings = 1;
+    thread_mutex_unlock(&_slave_mutex);
 }
 
 
@@ -120,7 +123,9 @@
  */
 void slave_rebuild_mounts (void)
 {
+    thread_mutex_lock(&_slave_mutex);
     update_settings = 1;
+    thread_mutex_unlock(&_slave_mutex);
 }
 
 
@@ -131,6 +136,7 @@
 
     slave_running = 1;
     max_interval = 0;
+    thread_mutex_create (&_slave_mutex);
     _slave_thread_id = thread_create("Slave Thread", _slave_thread, NULL, THREAD_ATTACHED);
 }
 
@@ -369,9 +375,13 @@
     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;
 }
@@ -697,8 +707,10 @@
     ice_config_t *config;
     unsigned int interval = 0;
 
+    thread_mutex_lock(&_slave_mutex);
     update_settings = 0;
     update_all_mounts = 0;
+    thread_mutex_unlock(&_slave_mutex);
 
     config = config_get_config();
     stats_global (config);
@@ -711,11 +723,13 @@
         int skip_timer = 0;
 
         /* re-read xml file if requested */
+        global_lock();
         if (global . schedule_config_reread)
         {
             event_config_read (NULL);
             global . schedule_config_reread = 0;
         }
+        global_unlock();
 
         thread_sleep (1000000);
         if (slave_running == 0)
@@ -724,6 +738,7 @@
         ++interval;
 
         /* only update relays lists when required */
+        thread_mutex_lock(&_slave_mutex);
         if (max_interval <= interval)
         {
             DEBUG0 ("checking master stream list");
@@ -733,6 +748,7 @@
                 skip_timer = 1;
             interval = 0;
             max_interval = config->master_update_interval;
+            thread_mutex_unlock(&_slave_mutex);
 
             /* the connection could take some time, so the lock can drop */
             if (update_from_master (config))
@@ -745,18 +761,23 @@
             config_release_config();
         }
         else
+        {
+            thread_mutex_unlock(&_slave_mutex);
             thread_mutex_lock (&(config_locks()->relay_lock));
+        }
 
         relay_check_streams (global.relays, cleanup_relays, skip_timer);
         relay_check_streams (global.master_relays, NULL, skip_timer);
         thread_mutex_unlock (&(config_locks()->relay_lock));
 
+        thread_mutex_lock(&_slave_mutex);
         if (update_settings)
         {
             source_recheck_mounts (update_all_mounts);
             update_settings = 0;
             update_all_mounts = 0;
         }
+        thread_mutex_unlock(&_slave_mutex);
     }
     INFO0 ("shutting down current relays");
     relay_check_streams (NULL, global.relays, 0);

Modified: icecast/trunk/icecast/src/source.c
===================================================================
--- icecast/trunk/icecast/src/source.c	2012-07-17 04:30:49 UTC (rev 18453)
+++ icecast/trunk/icecast/src/source.c	2012-07-17 14:03:37 UTC (rev 18454)
@@ -102,6 +102,7 @@
         /* make duplicates for strings or similar */
         src->mount = strdup (mount);
         src->max_listeners = -1;
+        thread_mutex_create(&src->lock);
 
         avl_insert (global.source_tree, src);
 
@@ -492,13 +493,15 @@
         }
         if (fds == 0)
         {
-            if (source->last_read + (time_t)source->timeout < current)
+            thread_mutex_lock(&source->lock);
+            if ((source->last_read + (time_t)source->timeout) < current)
             {
                 DEBUG3 ("last %ld, timeout %d, now %ld", (long)source->last_read,
                         source->timeout, (long)current);
                 WARN0 ("Disconnecting source due to socket timeout");
                 source->running = 0;
             }
+            thread_mutex_unlock(&source->lock);
             break;
         }
         source->last_read = current;
@@ -718,8 +721,10 @@
                 source->format->write_buf_to_file (source, refbuf);
         }
         /* lets see if we have too much data in the queue, but don't remove it until later */
+        thread_mutex_lock(&source->lock);
         if (source->queue_size > source->queue_size_limit)
             remove_from_q = 1;
+        thread_mutex_unlock(&source->lock);
 
         /* acquire write lock on pending_tree */
         avl_tree_wlock(source->pending_tree);
@@ -1169,13 +1174,16 @@
 
 /* update the specified source with details from the config or mount.
  * mountinfo can be NULL in which case default settings should be taken
+ * This function is called by the Slave thread
  */
 void source_update_settings (ice_config_t *config, source_t *source, mount_proxy *mountinfo)
 {
+    thread_mutex_lock(&source->lock);
     /*  skip if source is a fallback to file */
     if (source->running && source->client == NULL)
     {
         stats_event_hidden (source->mount, NULL, 1);
+        thread_mutex_unlock(&source->lock);
         return;
     }
     /* set global settings first */
@@ -1229,6 +1237,7 @@
     DEBUG1 ("burst size to %u", source->burst_size);
     DEBUG1 ("source timeout to %u", source->timeout);
     DEBUG1 ("fallback_when_full to %u", source->fallback_when_full);
+    thread_mutex_unlock(&source->lock);
 }
 
 

Modified: icecast/trunk/icecast/src/source.h
===================================================================
--- icecast/trunk/icecast/src/source.h	2012-07-17 04:30:49 UTC (rev 18453)
+++ icecast/trunk/icecast/src/source.h	2012-07-17 14:03:37 UTC (rev 18454)
@@ -17,11 +17,13 @@
 #include "yp.h"
 #include "util.h"
 #include "format.h"
+#include "thread/thread.h"
 
 #include <stdio.h>
 
 typedef struct source_tag
 {
+    mutex_t lock;
     client_t *client;
     connection_t *con;
     http_parser_t *parser;

Modified: icecast/trunk/icecast/src/stats.c
===================================================================
--- icecast/trunk/icecast/src/stats.c	2012-07-17 04:30:49 UTC (rev 18453)
+++ icecast/trunk/icecast/src/stats.c	2012-07-17 14:03:37 UTC (rev 18454)
@@ -631,9 +631,9 @@
 
     INFO0 ("stats thread started");
     while (_stats_running) {
+        thread_mutex_lock(&_global_event_mutex);
         if (_global_event_queue.head != NULL) {
             /* grab the next event from the queue */
-            thread_mutex_lock(&_global_event_mutex);
             event = _get_event_from_queue (&_global_event_queue);
             thread_mutex_unlock(&_global_event_mutex);
 
@@ -667,6 +667,10 @@
             thread_mutex_unlock(&_stats_mutex);
             continue;
         }
+        else
+        {
+            thread_mutex_unlock(&_global_event_mutex);
+        }
 
         thread_sleep(300000);
     }



More information about the commits mailing list