[xiph-commits] r16632 - in icecast/branches/kh/icecast: . src win32

karl at svn.xiph.org karl at svn.xiph.org
Sat Oct 10 18:20:05 PDT 2009


Author: karl
Date: 2009-10-10 18:20:04 -0700 (Sat, 10 Oct 2009)
New Revision: 16632

Modified:
   icecast/branches/kh/icecast/NEWS
   icecast/branches/kh/icecast/config.h.vc6
   icecast/branches/kh/icecast/configure.in
   icecast/branches/kh/icecast/src/client.c
   icecast/branches/kh/icecast/src/client.h
   icecast/branches/kh/icecast/src/connection.c
   icecast/branches/kh/icecast/src/format.c
   icecast/branches/kh/icecast/src/fserve.c
   icecast/branches/kh/icecast/src/slave.c
   icecast/branches/kh/icecast/src/source.c
   icecast/branches/kh/icecast/src/source.h
   icecast/branches/kh/icecast/win32/icecast2.iss
Log:
bump to kh17. fix failing relay crash case.  fix flashpolcy crash case.
fix memory corruption case when moving clients between workers.
some minor timing changes



Modified: icecast/branches/kh/icecast/NEWS
===================================================================
--- icecast/branches/kh/icecast/NEWS	2009-10-10 19:54:17 UTC (rev 16631)
+++ icecast/branches/kh/icecast/NEWS	2009-10-11 01:20:04 UTC (rev 16632)
@@ -16,6 +16,13 @@
 any extra tags are show in the conf/icecast.xml.dist file
 
 
+2.3.2-kh17
+. fix possible memory corruption when using multiple workers
+. a few minor timing changes, nothing major.
+. fix possible race case in multiple file handle close
+. kh16b. fix possible crash case with relay failing
+. kh16a. some fserve changes exposed a crash bug with flash clients.
+
 2.3.2-kh16
 . you can now fallback to file if the initial mountpont is not available as long
   as there is a limit-rate set at some point within the fallback chain.

Modified: icecast/branches/kh/icecast/config.h.vc6
===================================================================
--- icecast/branches/kh/icecast/config.h.vc6	2009-10-10 19:54:17 UTC (rev 16631)
+++ icecast/branches/kh/icecast/config.h.vc6	2009-10-11 01:20:04 UTC (rev 16632)
@@ -95,7 +95,7 @@
 #define PACKAGE_NAME "Icecast"
 
 /* Version number of package */
-#define VERSION "2.3.2-kh16"
+#define VERSION "2.3.2-kh17"
 
 /* Define to the version of this package. */
 #define PACKAGE_VERSION VERSION

Modified: icecast/branches/kh/icecast/configure.in
===================================================================
--- icecast/branches/kh/icecast/configure.in	2009-10-10 19:54:17 UTC (rev 16631)
+++ icecast/branches/kh/icecast/configure.in	2009-10-11 01:20:04 UTC (rev 16632)
@@ -1,4 +1,4 @@
-AC_INIT([Icecast], [2.3.2-kh16], [karl at xiph.org])
+AC_INIT([Icecast], [2.3.2-kh17], [karl at xiph.org])
 
 AC_PREREQ(2.59)
 AC_CONFIG_SRCDIR(src/main.c)

Modified: icecast/branches/kh/icecast/src/client.c
===================================================================
--- icecast/branches/kh/icecast/src/client.c	2009-10-10 19:54:17 UTC (rev 16631)
+++ icecast/branches/kh/icecast/src/client.c	2009-10-11 01:20:04 UTC (rev 16632)
@@ -317,29 +317,37 @@
 }
 
 
-void client_change_worker (client_t *client, worker_t *dest_worker)
+static void worker_add_client (worker_t *worker, client_t *client)
 {
+    *worker->last_p = client;
+    worker->last_p = &client->next_on_worker;
+    client->worker = worker;
+    ++worker->count;
+    if (worker->wakeup_ms - worker->time_ms > 15)
+        thread_cond_signal (&worker->cond); /* wake thread if required */
+}
+
+
+int client_change_worker (client_t *client, worker_t *dest_worker)
+{
     worker_t *this_worker = client->worker;
 
+    if (dest_worker->running == 0)
+        return 0;
     // make sure this client list is ok
     *this_worker->current_p = client->next_on_worker;
+    if (client->next_on_worker == NULL)
+        this_worker->last_p = this_worker->current_p;
     this_worker->count--;
     thread_mutex_unlock (&this_worker->lock);
     client->next_on_worker = NULL;
 
     thread_mutex_lock (&dest_worker->lock);
-    if (dest_worker->running)
-    {
-        client->worker = dest_worker;
-        *dest_worker->last_p = client;
-        dest_worker->last_p = &client->next_on_worker;
-        dest_worker->count++;
-        client->flags |= CLIENT_HAS_CHANGED_THREAD;
-        // make client inactive so that the destination thread does not run it straight away
-        client->flags &= ~CLIENT_ACTIVE;
-    }
+    worker_add_client (dest_worker, client);
+
     thread_mutex_unlock (&dest_worker->lock);
     thread_mutex_lock (&this_worker->lock);
+    return 1;
 }
 
 
@@ -354,12 +362,7 @@
     thread_rwlock_unlock (&workers_lock);
 
     client->schedule_ms = handler->time_ms;
-    *handler->last_p = client;
-    handler->last_p = &client->next_on_worker;
-    client->worker = handler;
-    ++handler->count;
-    if (handler->wakeup_ms - handler->time_ms > 15)
-        thread_cond_signal (&handler->cond); /* wake thread if required */
+    worker_add_client (handler, client);
     thread_mutex_unlock (&handler->lock);
 }
 
@@ -406,13 +409,9 @@
                     ret = client->ops->process (client);
 
                     /* special handler, client has moved away to another worker */
-                    if (client->flags & CLIENT_HAS_CHANGED_THREAD)
+                    if (ret > 0)
                     {
-                        client->flags &= ~CLIENT_HAS_CHANGED_THREAD;
-                        client->flags |= CLIENT_ACTIVE;
                         client = *prevp;
-                        if (client == NULL)
-                            handler->last_p = prevp;
                         continue;
                     }
                     if (ret < 0)

Modified: icecast/branches/kh/icecast/src/client.h
===================================================================
--- icecast/branches/kh/icecast/src/client.h	2009-10-10 19:54:17 UTC (rev 16631)
+++ icecast/branches/kh/icecast/src/client.h	2009-10-11 01:20:04 UTC (rev 16632)
@@ -131,7 +131,7 @@
 int  client_read_bytes (client_t *client, void *buf, unsigned len);
 void client_set_queue (client_t *client, refbuf_t *refbuf);
 
-void client_change_worker (client_t *client, worker_t *dest_worker);
+int  client_change_worker (client_t *client, worker_t *dest_worker);
 void client_add_worker (client_t *client);
 worker_t *find_least_busy_handler (void);
 void workers_adjust (int new_count);
@@ -141,7 +141,7 @@
 #define CLIENT_ACTIVE               (001)
 #define CLIENT_AUTHENTICATED        (002)
 #define CLIENT_IS_SLAVE             (004)
-#define CLIENT_HAS_CHANGED_THREAD   (010)
+
 #define CLIENT_NO_CONTENT_LENGTH    (020)
 #define CLIENT_HAS_INTRO_CONTENT    (040)
 #define CLIENT_FORMAT_BIT           (01000)

Modified: icecast/branches/kh/icecast/src/connection.c
===================================================================
--- icecast/branches/kh/icecast/src/connection.c	2009-10-10 19:54:17 UTC (rev 16631)
+++ icecast/branches/kh/icecast/src/connection.c	2009-10-11 01:20:04 UTC (rev 16632)
@@ -704,6 +704,7 @@
                 fb.flags = FS_NORMAL|FS_USE_ADMIN;
                 fb.fallback = NULL;
                 fb.limit = 0;
+                client->respcode = 200;
                 refbuf_release (refbuf);
                 client->shared_data = NULL;
                 client->check_buffer = format_generic_write_to_client;

Modified: icecast/branches/kh/icecast/src/format.c
===================================================================
--- icecast/branches/kh/icecast/src/format.c	2009-10-10 19:54:17 UTC (rev 16631)
+++ icecast/branches/kh/icecast/src/format.c	2009-10-11 01:20:04 UTC (rev 16632)
@@ -66,11 +66,20 @@
     if (format == NULL)
         return;
     rate_free (format->in_bitrate);
+    format->in_bitrate = NULL;
     rate_free (format->out_bitrate);
+    format->out_bitrate = NULL;
     free (format->charset);
     format->charset = NULL;
     if (format->free_plugin)
         format->free_plugin (format);
+    format->get_buffer = NULL;
+    format->write_buf_to_client = NULL;
+    format->write_buf_to_file = NULL;
+    format->create_client_data = NULL;
+    format->free_plugin = NULL;
+    format->set_tag = NULL;
+    format->apply_settings = NULL;
 }
 
 

Modified: icecast/branches/kh/icecast/src/fserve.c
===================================================================
--- icecast/branches/kh/icecast/src/fserve.c	2009-10-10 19:54:17 UTC (rev 16631)
+++ icecast/branches/kh/icecast/src/fserve.c	2009-10-11 01:20:04 UTC (rev 16632)
@@ -188,6 +188,7 @@
 static int _delete_fh (void *mapping)
 {
     fh_node *fh = mapping;
+    fh->refcount--;
     if (fh->refcount)
         WARN2 ("handle for %s has refcount %d", fh->finfo.mount, fh->refcount);
     else
@@ -242,6 +243,7 @@
     {
         free (fh);
         thread_mutex_lock (&result->lock);
+        avl_tree_unlock (fh_cache);
         result->refcount++;
         if (client)
         {
@@ -259,7 +261,6 @@
             }
         }
         DEBUG2 ("refcount now %d for %s", result->refcount, result->finfo.mount);
-        avl_tree_unlock (fh_cache);
         return result;
     }
 
@@ -578,11 +579,11 @@
 // fh must be locked before calling this
 static void fh_release (fh_node *fh)
 {
-    fh->refcount--;
     if (fh->finfo.mount[0])
         DEBUG2 ("refcount now %d on %s", fh->refcount, fh->finfo.mount);
-    if (fh->refcount)
+    if (fh->refcount > 1)
     {
+        fh->refcount--;
         thread_mutex_unlock (&fh->lock);
         return;
     }
@@ -592,7 +593,7 @@
     thread_mutex_unlock (&fh->lock);
     avl_tree_wlock (fh_cache);
     thread_mutex_lock (&fh->lock);
-    if (fh->refcount)
+    if (fh->refcount > 1)
         thread_mutex_unlock (&fh->lock);
     else
         avl_delete (fh_cache, fh, _delete_fh);
@@ -732,7 +733,7 @@
         if (written > 30000)
             break;
     }
-    client->schedule_ms = client->worker->time_ms + 150;
+    client->schedule_ms = client->worker->time_ms + 100;
     return 0;
 }
 

Modified: icecast/branches/kh/icecast/src/slave.c
===================================================================
--- icecast/branches/kh/icecast/src/slave.c	2009-10-10 19:54:17 UTC (rev 16631)
+++ icecast/branches/kh/icecast/src/slave.c	2009-10-11 01:20:04 UTC (rev 16632)
@@ -1259,8 +1259,7 @@
             source->flags &= ~SOURCE_RUNNING;
         if (relay->on_demand && source->listeners == 0)
             source->flags &= ~SOURCE_RUNNING;
-        source_read (source);
-        return 0;
+        return source_read (source);
     }
     if (relay->running && relay->enable)
     {

Modified: icecast/branches/kh/icecast/src/source.c
===================================================================
--- icecast/branches/kh/icecast/src/source.c	2009-10-10 19:54:17 UTC (rev 16631)
+++ icecast/branches/kh/icecast/src/source.c	2009-10-11 01:20:04 UTC (rev 16632)
@@ -72,8 +72,8 @@
 static int  http_source_listener (client_t *client);
 static int  http_source_intro (client_t *client);
 static int  locate_start_on_queue (source_t *source, client_t *client);
-static void listener_change_worker (client_t *client, source_t *source);
-static void source_change_worker (source_t *source);
+static int  listener_change_worker (client_t *client, source_t *source);
+static int  source_change_worker (source_t *source);
 static int  source_client_callback (client_t *client);
 
 #ifdef _WIN32
@@ -412,7 +412,7 @@
  * and sent back, however NULL is also valid as in the case of a short
  * timeout and there's no data pending.
  */
-void source_read (source_t *source)
+int source_read (source_t *source)
 {
     client_t *client = source->client;
     refbuf_t *refbuf = NULL;
@@ -445,11 +445,10 @@
         }
         if (current >= source->client_stats_update)
         {
-            source_change_worker (source);
             update_source_stats (source);
             source->client_stats_update = current + source->stats_interval;
-            thread_mutex_unlock (&source->lock);
-            return;
+            if (source_change_worker (source))
+                return 1;
         }
         if (source->limit_rate)
         {
@@ -486,6 +485,8 @@
                 source->skip_duration = 30;
             else
                 source->skip_duration = (long)(source->skip_duration * 1.8);
+                if (source->skip_duration > 700)
+                    source->skip_duration = 700;
             break;
         }
         source->skip_duration = (long)(source->skip_duration * 0.9);
@@ -570,6 +571,7 @@
     if (skip)
         client->schedule_ms = client->worker->time_ms + source->skip_duration;
     thread_mutex_unlock (&source->lock);
+    return 0;
 }
 
 
@@ -585,7 +587,7 @@
         INFO1 ("streaming duration expired on %s", source->mount);
     }
     if (source_running (source))
-        source_read (source);
+        return source_read (source);
     else
     {
         if ((source->flags & SOURCE_TERMINATING) == 0)
@@ -845,7 +847,8 @@
 
     // do we migrate this listener to the same handler as the source client
     if (source->client && source->client->worker != client->worker)
-        listener_change_worker (client, source);
+        if (listener_change_worker (client, source))
+            return 1;
 
     client->schedule_ms = client->worker->time_ms;
     while (loop)
@@ -867,12 +870,12 @@
         if (bytes < 0)
             break;  /* can't write any more */
 
-        client->schedule_ms += 100;
+        client->schedule_ms += 40;
         total_written += bytes;
         loop--;
     }
     if (loop == 0)
-        client->schedule_ms -= 500;
+        client->schedule_ms -= 190;
     rate_add (source->format->out_bitrate, total_written, client->worker->time_ms);
     global_add_bitrates (global.out_bitrate, total_written, client->worker->time_ms);
     source->bytes_sent_since_update += total_written;
@@ -1852,10 +1855,11 @@
 /* check to see if the source client can be moved to a less busy worker thread.
  * we only move the source client, not the listeners, they will move later
  */
-void source_change_worker (source_t *source)
+int source_change_worker (source_t *source)
 {
     client_t *client = source->client;
     worker_t *this_worker = client->worker, *worker;
+    int ret = 0;
 
     thread_rwlock_rlock (&workers_lock);
     worker = find_least_busy_handler ();
@@ -1864,22 +1868,26 @@
         if (worker->count + source->listeners + 10 < client->worker->count)
         {
             thread_mutex_unlock (&source->lock);
-            client_change_worker (client, worker);
-            DEBUG2 ("moving source from %p to %p", this_worker, worker);
-            thread_mutex_lock (&source->lock);
+            ret = client_change_worker (client, worker);
+            if (ret)
+                DEBUG2 ("moving source from %p to %p", this_worker, worker);
+            else
+                thread_mutex_lock (&source->lock);
         }
     }
     thread_rwlock_unlock (&workers_lock);
+    return ret;
 }
 
 
 /* move listener client to worker theread that the source is on. This will
  * help cache but prevent overloading a single worker with many listeners.
  */
-void listener_change_worker (client_t *client, source_t *source)
+int listener_change_worker (client_t *client, source_t *source)
 {
     worker_t *this_worker = client->worker, *dest_worker;
     long diff;
+    int ret = 0;
 
     thread_rwlock_rlock (&workers_lock);
     dest_worker = source->client->worker;
@@ -1888,10 +1896,13 @@
     if (diff < 1000 && this_worker != dest_worker)
     {
         thread_mutex_unlock (&source->lock);
-        client_change_worker (client, dest_worker);
-        DEBUG2 ("moving listener from %p to %p", this_worker, dest_worker);
-        thread_mutex_lock (&source->lock);
+        ret = client_change_worker (client, dest_worker);
+        if (ret)
+            DEBUG2 ("moving listener from %p to %p", this_worker, dest_worker);
+        else
+            thread_mutex_lock (&source->lock);
     }
     thread_rwlock_unlock (&workers_lock);
+    return ret;
 }
 

Modified: icecast/branches/kh/icecast/src/source.h
===================================================================
--- icecast/branches/kh/icecast/src/source.h	2009-10-10 19:54:17 UTC (rev 16631)
+++ icecast/branches/kh/icecast/src/source.h	2009-10-11 01:20:04 UTC (rev 16632)
@@ -106,7 +106,7 @@
 void source_main(source_t *source);
 void source_recheck_mounts (int update_all);
 int  source_add_listener (const char *mount, mount_proxy *mountinfo, client_t *client);
-void source_read (source_t *source);
+int  source_read (source_t *source);
 void source_setup_listener (source_t *source, client_t *client);
 void source_init (source_t *source);
 void source_shutdown (source_t *source, int with_fallback);

Modified: icecast/branches/kh/icecast/win32/icecast2.iss
===================================================================
--- icecast/branches/kh/icecast/win32/icecast2.iss	2009-10-10 19:54:17 UTC (rev 16631)
+++ icecast/branches/kh/icecast/win32/icecast2.iss	2009-10-11 01:20:04 UTC (rev 16632)
@@ -3,7 +3,7 @@
 
 [Setup]
 AppName=Icecast2-KH
-AppVerName=Icecast v2.3.2-kh16
+AppVerName=Icecast v2.3.2-kh17
 AppPublisherURL=http://www.icecast.org
 AppSupportURL=http://www.icecast.org
 AppUpdatesURL=http://www.icecast.org
@@ -13,10 +13,10 @@
 LicenseFile=..\COPYING
 InfoAfterFile=..\README
 OutputDir=.
-OutputBaseFilename=icecast2_win32_v2.3.2-kh16_setup
+OutputBaseFilename=icecast2_win32_v2.3.2-kh17_setup
 WizardImageFile=icecast2logo2.bmp
 WizardImageStretch=no
-VersionInfoProductVersion=kh16
+VersionInfoProductVersion=kh17
 VersionInfoVersion=2.3.2
 ; uncomment the following line if you want your installation to run on NT 3.51 too.
 ; MinVersion=4,3.51



More information about the commits mailing list