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

karl at svn.xiph.org karl at svn.xiph.org
Sat Jan 30 22:22:46 PST 2010


Author: karl
Date: 2010-01-30 22:22:46 -0800 (Sat, 30 Jan 2010)
New Revision: 16858

Modified:
   icecast/branches/kh/icecast/NEWS
   icecast/branches/kh/icecast/config.h.vc6
   icecast/branches/kh/icecast/configure.in
   icecast/branches/kh/icecast/src/auth.c
   icecast/branches/kh/icecast/src/auth_cmd.c
   icecast/branches/kh/icecast/src/cfgfile.c
   icecast/branches/kh/icecast/src/connection.c
   icecast/branches/kh/icecast/src/connection.h
   icecast/branches/kh/icecast/src/format.h
   icecast/branches/kh/icecast/src/format_mp3.c
   icecast/branches/kh/icecast/src/format_ogg.c
   icecast/branches/kh/icecast/src/logging.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 kh20. fixes only.
lock imbalance fix with workers > 1, seemed to affect FBSD.
moved sources count change for relays as that was increasing over restarts.
memory leak plugged on source_t removal.
double free prevented on listener_remove
auth_cmd stall fix.
small code cleanup


Modified: icecast/branches/kh/icecast/NEWS
===================================================================
--- icecast/branches/kh/icecast/NEWS	2010-01-30 20:05:26 UTC (rev 16857)
+++ icecast/branches/kh/icecast/NEWS	2010-01-31 06:22:46 UTC (rev 16858)
@@ -11,11 +11,28 @@
   max-listener/bandwidth check. slaves can use a different auth to listeners
 . mount can filter out theora content, useful for defining a local relay
   of a theora+vorbis stream to have a vorbis only stream from the same source.
-. handlers options for url authenticator.
+. handlers setting for URL authenticator, for N requests at a time.
 
 any extra tags are show in the conf/icecast.xml.dist file
 
 
+2.3.2-kh20
+. fix possible lock imbalance bug if mutliple workers set
+. make sure listeners are not paused if relay is not running
+. fix memory leak on each source disconnection.
+. fix double free corruption bug if listener_remove used.
+. on server shutdown, prevent auth of new listeners only. other auth requests
+  can continue which allows client details to clean up properly
+. relocate where the source count is increased. For source clients it is just
+  before where it used to be but for relays it is increased before a relay
+  connection is attempted. Bug in kh19 meant sources kept increasing on relay
+  restart
+. fix possible stalling bug in auth command method.
+. listener_connections stat could have a random data bug
+. Do not force a master relay recheck on stream start/stop
+. build fix on certain platforms.
+. small internal code cleanups.
+
 2.3.2-kh19
 . add 7.xsl processing to present stats for a shoutcast /7.html request, requires
   alias of /7.html to /7.xsl

Modified: icecast/branches/kh/icecast/config.h.vc6
===================================================================
--- icecast/branches/kh/icecast/config.h.vc6	2010-01-30 20:05:26 UTC (rev 16857)
+++ icecast/branches/kh/icecast/config.h.vc6	2010-01-31 06:22:46 UTC (rev 16858)
@@ -95,7 +95,7 @@
 #define PACKAGE_NAME "Icecast"
 
 /* Version number of package */
-#define VERSION "2.3.2-kh19"
+#define VERSION "2.3.2-kh20"
 
 /* Define to the version of this package. */
 #define PACKAGE_VERSION VERSION

Modified: icecast/branches/kh/icecast/configure.in
===================================================================
--- icecast/branches/kh/icecast/configure.in	2010-01-30 20:05:26 UTC (rev 16857)
+++ icecast/branches/kh/icecast/configure.in	2010-01-31 06:22:46 UTC (rev 16858)
@@ -1,4 +1,4 @@
-AC_INIT([Icecast], [2.3.2-kh19], [karl at xiph.org])
+AC_INIT([Icecast], [2.3.2-kh20], [karl at xiph.org])
 
 LT_INIT
 AC_PREREQ(2.59)

Modified: icecast/branches/kh/icecast/src/auth.c
===================================================================
--- icecast/branches/kh/icecast/src/auth.c	2010-01-30 20:05:26 UTC (rev 16857)
+++ icecast/branches/kh/icecast/src/auth.c	2010-01-31 06:22:46 UTC (rev 16858)
@@ -224,9 +224,9 @@
 
     /* make sure there is still a client at this point, a slow backend request
      * can be avoided if client has disconnected */
-    if (is_listener_connected (client) == 0)
+    if (allow_auth == 0 || is_listener_connected (client) == 0)
     {
-        DEBUG0 ("listener is no longer connected");
+        DEBUG0 ("dropping listener connection");
         client->respcode = 400;
         return;
     }
@@ -257,7 +257,10 @@
     auth_user->auth = NULL;
     /* client is going, so auth is not an issue at this point */
     auth_user->client->flags &= ~CLIENT_AUTHENTICATED;
-    client_send_404 (auth_user->client, "Failed relay");
+    if (auth_user->client->respcode == 0)
+        client_send_404 (auth_user->client, "Failed relay");
+    else
+        auth_user->client->flags |= CLIENT_ACTIVE;
     auth_user->client = NULL;
 }
 
@@ -339,7 +342,7 @@
             auth_user->thread_data = handler->data;
             auth_user->handler = handler->id;
 
-            if (allow_auth && auth_user->process)
+            if (auth_user->process)
             {
                 worker_t *worker = NULL;
                 if (auth_user->client)
@@ -575,6 +578,7 @@
         if (mount && mountinfo && mountinfo->auth && mountinfo->auth->release_listener)
         {
             auth_client *auth_user = auth_client_setup (mount, client);
+            client->flags &= ~CLIENT_ACTIVE;
             auth_user->process = auth_remove_listener;
             queue_auth_client (auth_user, mountinfo);
             return 0;

Modified: icecast/branches/kh/icecast/src/auth_cmd.c
===================================================================
--- icecast/branches/kh/icecast/src/auth_cmd.c	2010-01-30 20:05:26 UTC (rev 16857)
+++ icecast/branches/kh/icecast/src/auth_cmd.c	2010-01-31 06:22:46 UTC (rev 16858)
@@ -229,10 +229,10 @@
         case 0: /* child */
             dup2 (outfd[0], 0);
             dup2 (infd[1], 1);
-            close (outfd[0]);
-            close (infd[1]);
-            if (execl (cmd->listener_add, cmd->listener_add, NULL) < 0)
-                ERROR1 ("unable to exec command \"%s\"", cmd->listener_add);
+            close (outfd[1]);
+            close (infd[0]);
+            execl (cmd->listener_add, cmd->listener_add, NULL);
+            ERROR1 ("unable to exec command \"%s\"", cmd->listener_add);
             exit (-1);
         case -1:
             break;

Modified: icecast/branches/kh/icecast/src/cfgfile.c
===================================================================
--- icecast/branches/kh/icecast/src/cfgfile.c	2010-01-30 20:05:26 UTC (rev 16857)
+++ icecast/branches/kh/icecast/src/cfgfile.c	2010-01-31 06:22:46 UTC (rev 16858)
@@ -277,6 +277,8 @@
     auth_release (mount->auth);
     if (mount->access_log.logid >= 0)
         log_close (mount->access_log.logid);
+    xmlFree (mount->access_log.name);
+    xmlFree (mount->access_log.exclude_ext);
     free (mount);
 }
 

Modified: icecast/branches/kh/icecast/src/connection.c
===================================================================
--- icecast/branches/kh/icecast/src/connection.c	2010-01-30 20:05:26 UTC (rev 16857)
+++ icecast/branches/kh/icecast/src/connection.c	2010-01-31 06:22:46 UTC (rev 16858)
@@ -925,86 +925,47 @@
 /* Called when activating a source. Verifies that the source count is not
  * exceeded and applies any initial parameters.
  */
-int connection_complete_source (source_t *source, int response)
+int connection_complete_source (source_t *source, http_parser_t *parser)
 {
-    ice_config_t *config = config_get_config();
+    const char *contenttype = httpp_getvar (parser, "content-type");
+    mount_proxy *mountinfo;
+    format_type_t format_type;
+    ice_config_t *config;
 
-    global_lock ();
-    DEBUG1 ("sources count is %d", global.sources);
-
-    if (global.sources < config->source_limit)
+    /* setup format handler */
+    if (contenttype != NULL)
     {
-        const char *contenttype;
-        mount_proxy *mountinfo;
-        format_type_t format_type;
+        format_type = format_get_type (contenttype);
 
-        /* setup format handler */
-        contenttype = httpp_getvar (source->parser, "content-type");
-        if (contenttype != NULL)
+        if (format_type == FORMAT_ERROR)
         {
-            format_type = format_get_type (contenttype);
-
-            if (format_type == FORMAT_ERROR)
-            {
-                global_unlock();
-                config_release_config();
-                if (response)
-                {
-                    client_send_403 (source->client, "Content-type not supported");
-                    source->client = NULL;
-                }
-                WARN1("Content-type \"%s\" not supported, dropping source", contenttype);
-                return -1;
-            }
-        }
-        else
-        {
-            WARN0("No content-type header, falling back to backwards compatibility mode "
-                    "for icecast 1.x relays. Assuming content is mp3.");
-            format_type = FORMAT_TYPE_GENERIC;
-        }
-
-        source->format->type = format_type;
-        source->format->mount = source->mount;
-        source->format->parser = source->parser;
-        if (format_get_plugin (source->format) < 0)
-        {
-            global_unlock();
-            config_release_config();
-            if (response)
-            {
-                client_send_403 (source->client, "internal format allocation problem");
-                source->client = NULL;
-            }
-            WARN1 ("plugin format failed for \"%s\"", source->mount);
+            WARN1("Content-type \"%s\" not supported, dropping source", contenttype);
             return -1;
         }
-
-        global.sources++;
-        stats_event_args (NULL, "sources", "%d", global.sources);
-        global_unlock();
-
-        mountinfo = config_find_mount (config, source->mount);
-        source_update_settings (config, source, mountinfo);
-        INFO1 ("source %s is ready to start", source->mount);
-        config_release_config();
-        slave_rebuild_mounts();
-
-        return 0;
     }
-    WARN1("Request to add source when maximum source limit "
-            "reached %d", global.sources);
+    else
+    {
+        WARN0("No content-type header, falling back to backwards compatibility mode "
+                "for icecast 1.x relays. Assuming content is mp3.");
+        format_type = FORMAT_TYPE_GENERIC;
+    }
 
-    global_unlock();
-    config_release_config();
-
-    if (response)
+    source->format->type = format_type;
+    source->format->mount = source->mount;
+    source->format->parser = parser;
+    if (format_get_plugin (source->format) < 0)
     {
-        client_send_403 (source->client, "too many sources connected");
-        source->client = NULL;
+        WARN1 ("plugin format failed for \"%s\"", source->mount);
+        return -1;
     }
 
-    return -1;
+    config = config_get_config();
+    mountinfo = config_find_mount (config, source->mount);
+    source_update_settings (config, source, mountinfo);
+    INFO1 ("source %s is ready to start", source->mount);
+    config_release_config();
+
+    return 0;
 }
 
 
@@ -1157,7 +1118,7 @@
     {
         WARN0 ("source mountpoint not starting with /");
         client_send_401 (client, NULL);
-        return 1;
+        return 0;
     }
     switch (auth_check_source (client, uri))
     {

Modified: icecast/branches/kh/icecast/src/connection.h
===================================================================
--- icecast/branches/kh/icecast/src/connection.h	2010-01-30 20:05:26 UTC (rev 16857)
+++ icecast/branches/kh/icecast/src/connection.h	2010-01-31 06:22:46 UTC (rev 16858)
@@ -58,7 +58,7 @@
 int  connection_setup_sockets (struct ice_config_tag *config);
 void connection_close(connection_t *con);
 int  connection_init (connection_t *con, sock_t sock);
-int connection_complete_source (struct source_tag *source, int response);
+int  connection_complete_source (struct source_tag *source, http_parser_t *parser);
 void connection_uses_ssl (connection_t *con);
 #ifdef HAVE_OPENSSL
 int  connection_read_ssl (connection_t *con, void *buf, size_t len);

Modified: icecast/branches/kh/icecast/src/format.h
===================================================================
--- icecast/branches/kh/icecast/src/format.h	2010-01-30 20:05:26 UTC (rev 16857)
+++ icecast/branches/kh/icecast/src/format.h	2010-01-31 06:22:46 UTC (rev 16858)
@@ -54,7 +54,7 @@
     int (*create_client_data)(format_plugin_t *plugin, client_t *client);
     void (*set_tag)(struct _format_plugin_tag *plugin, const char *tag, const char *value, const char *charset);
     void (*free_plugin)(struct _format_plugin_tag *self);
-    void (*apply_settings)(client_t *client, struct _format_plugin_tag *format, struct _mount_proxy *mount);
+    void (*apply_settings)(struct _format_plugin_tag *format, struct _mount_proxy *mount);
     int (*get_image)(client_t *client, struct _format_plugin_tag *format);
 
     /* for internal state management */

Modified: icecast/branches/kh/icecast/src/format_mp3.c
===================================================================
--- icecast/branches/kh/icecast/src/format_mp3.c	2010-01-30 20:05:26 UTC (rev 16857)
+++ icecast/branches/kh/icecast/src/format_mp3.c	2010-01-31 06:22:46 UTC (rev 16858)
@@ -56,7 +56,7 @@
 static int format_mp3_write_buf_to_client(client_t *client);
 static void write_mp3_to_file (struct source_tag *source, refbuf_t *refbuf);
 static void mp3_set_tag (format_plugin_t *plugin, const char *tag, const char *in_value, const char *charset);
-static void format_mp3_apply_settings(client_t *client, format_plugin_t *format, mount_proxy *mount);
+static void format_mp3_apply_settings (format_plugin_t *format, mount_proxy *mount);
 
 
 typedef struct {
@@ -198,7 +198,7 @@
 }
 
 
-static void format_mp3_apply_settings (client_t *client, format_plugin_t *format, mount_proxy *mount)
+static void format_mp3_apply_settings (format_plugin_t *format, mount_proxy *mount)
 {
     mp3_state *source_mp3 = format->_state;
 
@@ -218,7 +218,7 @@
     }
     if (source_mp3->interval < 0)
     {
-        const char *metadata = httpp_getvar (client->parser, "icy-metaint");
+        const char *metadata = httpp_getvar (format->parser, "icy-metaint");
         source_mp3->interval = ICY_METADATA_INTERVAL;
         if (metadata)
         {

Modified: icecast/branches/kh/icecast/src/format_ogg.c
===================================================================
--- icecast/branches/kh/icecast/src/format_ogg.c	2010-01-30 20:05:26 UTC (rev 16857)
+++ icecast/branches/kh/icecast/src/format_ogg.c	2010-01-31 06:22:46 UTC (rev 16858)
@@ -58,8 +58,7 @@
 static void write_ogg_to_file (struct source_tag *source, refbuf_t *refbuf);
 static refbuf_t *ogg_get_buffer (source_t *source);
 static int write_buf_to_client (client_t *client);
-static void apply_ogg_settings (client_t *client,
-        format_plugin_t *format, mount_proxy *mount);
+static void apply_ogg_settings (format_plugin_t *format, mount_proxy *mount);
 
 
 struct ogg_client
@@ -203,8 +202,7 @@
 }
 
 
-static void apply_ogg_settings (client_t *client,
-        format_plugin_t *format, mount_proxy *mount)
+static void apply_ogg_settings (format_plugin_t *format, mount_proxy *mount)
 {
     ogg_state_t *ogg_info = format->_state;
 

Modified: icecast/branches/kh/icecast/src/logging.c
===================================================================
--- icecast/branches/kh/icecast/src/logging.c	2010-01-30 20:05:26 UTC (rev 16857)
+++ icecast/branches/kh/icecast/src/logging.c	2010-01-31 06:22:46 UTC (rev 16858)
@@ -29,6 +29,7 @@
 #include "cfgfile.h"
 #include "logging.h"
 #include "util.h"
+#include "errno.h"
 
 void fatal_error (const char *perr);
 

Modified: icecast/branches/kh/icecast/src/slave.c
===================================================================
--- icecast/branches/kh/icecast/src/slave.c	2010-01-30 20:05:26 UTC (rev 16857)
+++ icecast/branches/kh/icecast/src/slave.c	2010-01-31 06:22:46 UTC (rev 16858)
@@ -177,7 +177,6 @@
 {
     update_all_mounts = 1;
     update_settings = 1;
-    streamlist_check = 0;
 }
 
 
@@ -189,6 +188,7 @@
     restart_connection_thread = 1;
     redirector_clearall();
     slave_update_all_mounts ();
+    streamlist_check = 0;
 }
 
 /* Request slave thread to check the relay list for changes and to
@@ -463,16 +463,16 @@
         if (ret < 0)
             continue;
         source_clear_source (src); // clear any old data
-        src->parser = client->parser;
 
-        if (connection_complete_source (src, 0) < 0)
+        if (connection_complete_source (src, client->parser) < 0)
         {
-            INFO0("Failed to complete source initialisation");
+            WARN1 ("Failed to complete initialisation on %s", relay->localmount);
             continue;
         }
+        src->parser = client->parser;
         return 1;
     } while ((master = master->next) && global.running == ICE_RUNNING);
-    return 0;
+    return -1;
 }
 
 static void *start_relay_stream (void *arg)
@@ -480,39 +480,60 @@
     relay_server *relay = arg;
     source_t *src = relay->source;
     client_t *client = src->client;
+    int failed = 1, sources;
 
-    INFO1("Starting relayed source at mountpoint \"%s\"", relay->localmount);
-    thread_rwlock_rlock (&global.shutdown_lock);
-    thread_mutex_lock (&src->lock);
-    src->flags |= SOURCE_RESTART_RELAY;
+    global_lock();
+    sources = ++global.sources;
+    stats_event_args (NULL, "sources", "%d", global.sources);
+    global_unlock();
+    do
+    {
+        ice_config_t *config = config_get_config();
 
-    if (open_relay (relay))
-    {
+        thread_rwlock_rlock (&global.shutdown_lock);
+        thread_mutex_lock (&src->lock);
+        src->flags |= SOURCE_PAUSE_LISTENERS;
+        if (sources > config->source_limit)
+        {
+            config_release_config();
+            WARN1 ("starting relayed mountpoint \"%s\" requires a higher sources limit", relay->localmount);
+            break;
+        }
+        config_release_config();
+        INFO1("Starting relayed source at mountpoint \"%s\"", relay->localmount);
+
+        if (open_relay (relay) < 0)
+            break;
         stats_event_inc (NULL, "source_relay_connections");
         source_init (src);
-    }
-    else
+        failed = 0;
+    } while (0);
+
+    relay->running = 1;
+    client->ops = &relay_client_ops;
+    client->schedule_ms = timing_get_time();
+
+    if (failed)
     {
         /* failed to start, better clean up and reset */
         if (relay->on_demand == 0)
             yp_remove (relay->localmount);
 
         INFO2 ("listener count remaining on %s is %d", src->mount, src->listeners);
-        src->flags &= ~SOURCE_RESTART_RELAY;
+        src->flags &= ~SOURCE_PAUSE_LISTENERS;
         thread_mutex_unlock (&src->lock);
+        relay->start = client->schedule_ms/1000;
+        if (relay->on_demand)
+            relay->start += 5;
+        else
+            relay->start += relay->interval;
     }
 
-    relay->running = 1;
-    client->ops = &relay_client_ops;
-
     thread_spin_lock (&relay_start_lock);
     relays_connecting--;
     thread_spin_unlock (&relay_start_lock);
 
     thread_mutex_lock (&client->worker->lock);
-    client->schedule_ms = timing_get_time();
-    relay->start = 0;
-    client->schedule_ms += 1000;
     client->flags |= CLIENT_ACTIVE;
     thread_cond_signal (&client->worker->cond);
     thread_mutex_unlock (&client->worker->lock);
@@ -1213,18 +1234,18 @@
         // fallback listeners unless relay is to be retried
         source_shutdown (source, fallback);
         source->flags |= SOURCE_TERMINATING;
+        if (relay->running == 0) /* don't pause listeners if relay shutting down */
+            source->flags &= ~SOURCE_PAUSE_LISTENERS;
     }
-    if (source->termination_count)
+    if (source->termination_count && source->termination_count <= source->listeners)
     {
         client->schedule_ms = client->worker->time_ms + 150;
-        DEBUG2 ("counts are %d and %d", source->termination_count, source->listeners);
+        DEBUG3 ("counts are %lu and %lu (%s)", source->termination_count, source->listeners, source->mount);
         thread_mutex_unlock (&source->lock);
         return 0;
     }
     DEBUG1 ("all listeners have now been checked on %s", relay->localmount);
-    if ((source->flags & SOURCE_RESTART_RELAY) == 0 && relay->on_demand == 0)
-        relay->start = client->worker->current_time.tv_sec + relay->interval;
-    source->flags &= ~(SOURCE_TERMINATING|SOURCE_RESTART_RELAY);
+    source->flags &= ~SOURCE_TERMINATING;
     client->ops = &relay_startup_ops;
     if (relay->running && relay->enable)
     {
@@ -1247,13 +1268,13 @@
             ret = 0;
         }
         thread_mutex_unlock (&source->lock);
-        global_lock();
-        global.sources--;
-        stats_event_args (NULL, "sources", "%d", global.sources);
-        global_unlock();
         stats_event (relay->localmount, NULL, NULL); // needed???
         slave_update_all_mounts();
     }
+    global_lock();
+    global.sources--;
+    stats_event_args (NULL, "sources", "%d", global.sources);
+    global_unlock();
     global_reduce_bitrate_sampling (global.out_bitrate);
     thread_rwlock_unlock (&global.shutdown_lock);
     return ret;

Modified: icecast/branches/kh/icecast/src/source.c
===================================================================
--- icecast/branches/kh/icecast/src/source.c	2010-01-30 20:05:26 UTC (rev 16857)
+++ icecast/branches/kh/icecast/src/source.c	2010-01-31 06:22:46 UTC (rev 16858)
@@ -362,6 +362,7 @@
     /* There should be no listeners on this mount */
     if (source->listeners)
         WARN1("active listeners on mountpoint %s", source->mount);
+    avl_tree_free (source->clients, NULL);
 
     thread_mutex_unlock (&source->lock);
     thread_mutex_destroy (&source->lock);
@@ -497,7 +498,7 @@
             {
                 DEBUG3 ("last %ld, timeout %d, now %ld", (long)source->last_read,
                         source->timeout, (long)current);
-                WARN0 ("Disconnecting source due to socket timeout");
+                WARN1 ("Disconnecting %s due to socket timeout", source->mount);
                 source->flags &= ~SOURCE_RUNNING;
                 skip = 0;
                 break;
@@ -521,6 +522,7 @@
             {
                 source->bytes_read_since_update += refbuf->len;
 
+                refbuf->flags |= SOURCE_QUEUE_BLOCK;
                 /* the latest refbuf is counted twice so that it stays */
                 refbuf_addref (refbuf);
 
@@ -616,9 +618,9 @@
             source_shutdown (source, 1);
             source->flags |= SOURCE_TERMINATING;
         }
-        if (source->termination_count)
+        if (source->termination_count && source->termination_count <= source->listeners)
         {
-            DEBUG3 ("%s waiting (%d, %d)", source->mount, source->termination_count, source->listeners);
+            DEBUG3 ("%s waiting (%lu, %lu)", source->mount, source->termination_count, source->listeners);
             client->schedule_ms = client->worker->time_ms + 200;
         }
         else
@@ -827,6 +829,8 @@
         return -1;
     thread_mutex_lock (&source->lock);
     ret = send_listener (source, client);
+    if (ret == 1)
+        return 0;
     if (ret < 0)
         ret = source_listener_release (source, client);
     thread_mutex_unlock (&source->lock);
@@ -867,9 +871,11 @@
     if (source->flags & SOURCE_TERMINATING)
     {
         source->termination_count--;
-        DEBUG2 ("termination count on %s now %d", source->mount, source->termination_count);
-        if (source->flags & SOURCE_RESTART_RELAY && global.running == ICE_RUNNING)
+        DEBUG2 ("termination count on %s now %lu", source->mount, source->termination_count);
+        if ((source->flags & SOURCE_PAUSE_LISTENERS) && global.running == ICE_RUNNING)
         {
+            if (client->refbuf && (client->refbuf->flags & SOURCE_QUEUE_BLOCK))
+                client_set_queue (client, NULL);
             client->ops = &listener_pause_ops;
             client->schedule_ms = client->worker->time_ms + 100;
             return 0;
@@ -965,6 +971,7 @@
     stats_event (source->mount, "server_type", source->format->contenttype);
     stats_event_flags (source->mount, "listener_peak", "0", STATS_COUNTERS);
     stats_event_args (source->mount, "listener_peak", "%lu", source->peak_listeners);
+    stats_event_flags (source->mount, "listener_connections", "0", STATS_COUNTERS);
     stats_event_time (source->mount, "stream_start");
     stats_event_flags (source->mount, "total_mbytes_sent", "0", STATS_COUNTERS);
     stats_event_flags (source->mount, "total_bytes_sent", "0", STATS_COUNTERS);
@@ -995,10 +1002,6 @@
 
     thread_mutex_unlock (&source->lock);
 
-    /* on demand relays should of already called this */
-    if ((source->flags & SOURCE_ON_DEMAND) == 0)
-        slave_update_all_mounts();
-
     mountinfo = config_find_mount (config_get_config(), source->mount);
     if (mountinfo)
     {
@@ -1020,6 +1023,10 @@
 
     INFO1 ("Source %s initialised", source->mount);
     source->flags |= SOURCE_RUNNING;
+
+    /* on demand relays should of already called this */
+    if ((source->flags & SOURCE_ON_DEMAND) == 0)
+        slave_update_all_mounts();
 }
 
 
@@ -1144,7 +1151,7 @@
 
     /* to be done before possible non-utf8 stats */
     if (source->format && source->format->apply_settings)
-        source->format->apply_settings (source->client, source->format, mountinfo);
+        source->format->apply_settings (source->format, mountinfo);
 
     /* public */
     if (mountinfo && mountinfo->yp_public >= 0)
@@ -1416,7 +1423,6 @@
     if (agent)
         stats_event (source->mount, "user_agent", agent);
     stats_event_inc(NULL, "source_client_connections");
-    stats_event_flags (source->mount, "listener_connections", "0", STATS_COUNTERS);
 
     source_init (source);
     client->ops = &source_client_ops;
@@ -1576,7 +1582,8 @@
             return -1;
     }
     thread_mutex_lock (&source->lock);
-    DEBUG1 ("remaining listeners to process is %d", source->listeners);
+    if (source->listeners)
+        DEBUG1 ("remaining listeners to process is %d", source->listeners);
     /* listeners handled now */
     if (source->wait_time)
     {
@@ -1840,15 +1847,32 @@
 
     if (source)
     {
+        ice_config_t *config = config_get_config();
+        global_lock();
+        if (global.sources >= config->source_limit)
+        {
+            config_release_config();
+            WARN1 ("Request to add source when maximum source limit reached %d", global.sources);
+            global_unlock();
+            client_send_403 (client, "too many streams connected");
+            source_free_source (source);
+            return 0;
+        }
+        config_release_config();
+        global.sources++;
+        INFO1 ("sources count is now %d", global.sources);
+        stats_event_args (NULL, "sources", "%d", global.sources);
+        global_unlock();
         thread_mutex_lock (&source->lock);
-        source->client = client;
-        source->parser = client->parser;
-        if (connection_complete_source (source, 1) < 0)
+        if (connection_complete_source (source, client->parser) < 0)
         {
+            client_send_403 (client, "content type not supported");
             thread_mutex_unlock (&source->lock);
             source_free_source (source);
-            return -1;
+            return 0;
         }
+        source->client = client;
+        source->parser = client->parser;
         client->respcode = 200;
         client->shared_data = source;
 

Modified: icecast/branches/kh/icecast/src/source.h
===================================================================
--- icecast/branches/kh/icecast/src/source.h	2010-01-30 20:05:26 UTC (rev 16857)
+++ icecast/branches/kh/icecast/src/source.h	2010-01-31 06:22:46 UTC (rev 16858)
@@ -80,7 +80,7 @@
 
 #define SOURCE_RUNNING              01
 #define SOURCE_ON_DEMAND            02
-#define SOURCE_RESTART_RELAY        04
+#define SOURCE_PAUSE_LISTENERS      04
 #define SOURCE_SHOUTCAST_COMPAT     010
 #define SOURCE_TERMINATING          020
 #define SOURCE_TEMPORARY_FALLBACK   040
@@ -111,6 +111,7 @@
 
 #define SOURCE_BLOCK_SYNC           01
 #define SOURCE_BLOCK_RELEASE        02
+#define SOURCE_QUEUE_BLOCK          04
 
 #endif
 

Modified: icecast/branches/kh/icecast/win32/icecast2.iss
===================================================================
--- icecast/branches/kh/icecast/win32/icecast2.iss	2010-01-30 20:05:26 UTC (rev 16857)
+++ icecast/branches/kh/icecast/win32/icecast2.iss	2010-01-31 06:22:46 UTC (rev 16858)
@@ -1,71 +1,74 @@
-; Script generated by the Inno Setup Script Wizard.
-; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
-
-[Setup]
-AppName=Icecast2-KH
-AppVerName=Icecast v2.3.2-kh19
-AppPublisherURL=http://www.icecast.org
-AppSupportURL=http://www.icecast.org
-AppUpdatesURL=http://www.icecast.org
-DefaultDirName={pf}\Icecast2 Win32 KH
-DefaultGroupName=Icecast2 Win32 KH
-AllowNoIcons=yes
-LicenseFile=..\COPYING
-InfoAfterFile=..\README
-OutputDir=.
-OutputBaseFilename=icecast2_win32_v2.3.2-kh19_setup
-WizardImageFile=icecast2logo2.bmp
-WizardImageStretch=no
-VersionInfoProductVersion=kh19
-VersionInfoVersion=2.3.2
-; uncomment the following line if you want your installation to run on NT 3.51 too.
-; MinVersion=4,3.51
-
-[Tasks]
-Name: "desktopicon"; Description: "Create a &desktop icon"; GroupDescription: "Additional icons:"; MinVersion: 4,4
-
-[Dirs]
-Name: "{app}\web"
-Name: "{app}\admin"
-Name: "{app}\doc"
-Name: "{app}\logs"
-Name: "{app}\examples"
-
-
-[Files]
-Source: "win_release\icecast2win.exe"; DestDir: "{app}"; Flags: ignoreversion
-Source: "console_release\icecast2_console.exe"; DestDir: "{app}"; DestName: "icecast2console.exe"; Flags: ignoreversion
-Source: "service_Release\icecastService.exe"; DestDir: "{app}"; Flags: ignoreversion
-Source: "..\examples\*"; DestDir: "{app}\examples"; Excludes: "*~"; Flags: ignoreversion
-Source: "..\doc\*"; DestDir: "{app}\doc"; Excludes: "*Makefile*"; Flags: ignoreversion
-Source: "..\web\*.xsl"; DestDir: "{app}\web"; Flags: ignoreversion
-Source: "..\web\*.html"; DestDir: "{app}\web"; Flags: ignoreversion
-Source: "..\web\images\*.png"; DestDir: "{app}\web\images"; Flags: ignoreversion
-Source: "..\web\images\*.jpg"; DestDir: "{app}\web\images"; Flags: ignoreversion
-Source: "..\web\*.css"; DestDir: "{app}\web"; Flags: ignoreversion
-Source: "..\admin\*.xsl"; DestDir: "{app}\admin"; Flags: ignoreversion
-Source: "..\admin\flashpolicy"; DestDir: "{app}\admin"; Flags: ignoreversion
-Source: "..\conf\*.dist"; DestDir: "{app}"; Flags: ignoreversion
-Source: "..\examples\icecast_shoutcast_compat.xml"; DestDir: "{app}"; DestName: "icecast.xml"; Flags: ignoreversion confirmoverwrite
-Source: ".\pthreadVSE.dll"; DestDir: "{app}"; Flags: ignoreversion
-Source: ".\iconv.dll"; DestDir: "{app}"; Flags: ignoreversion
-Source: ".\ogg.dll"; DestDir: "{app}"; Flags: ignoreversion
-Source: ".\libspeex.dll"; DestDir: "{app}"; Flags: ignoreversion
-Source: ".\libxslt.dll"; DestDir: "{app}"; Flags: ignoreversion
-Source: ".\libxml2.dll"; DestDir: "{app}"; Flags: ignoreversion
-Source: ".\libcurl.dll"; DestDir: "{app}"; Flags: ignoreversion
-Source: ".\libeay32.dll"; DestDir: "{app}"; Flags: ignoreversion
-Source: ".\ssleay32.dll"; DestDir: "{app}"; Flags: ignoreversion
-Source: ".\zlib1.dll"; DestDir: "{app}"; Flags: ignoreversion
-
-[Icons]
-
-Name: "{group}\Icecast2 Win32"; Filename: "{app}\icecast2win.exe";WorkingDir: "{app}";
-Name: "{userdesktop}\Icecast2 Win32"; Filename: "{app}\icecast2win.exe"; MinVersion: 4,4; Tasks: desktopicon;WorkingDir: "{app}";
-
-[Run]
-Filename: "{app}\icecastService.exe"; Parameters: "install ""{app}""";Description: "Install Icecast as a windows service.";Flags: postinstall
-
-[UninstallRun]
-Filename: "{app}\icecastService.exe"; Parameters: "remove"
-
+; Script generated by the Inno Setup Script Wizard.
+; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
+
+[Setup]
+AppName=Icecast2-KH
+AppVerName=Icecast v2.3.2-kh20
+AppPublisherURL=http://www.icecast.org
+AppSupportURL=http://www.icecast.org
+AppUpdatesURL=http://www.icecast.org
+DefaultDirName={pf}\Icecast2 Win32 KH
+DefaultGroupName=Icecast2 Win32 KH
+AllowNoIcons=yes
+LicenseFile=..\COPYING
+InfoAfterFile=..\README
+OutputDir=.
+OutputBaseFilename=icecast2_win32_v2.3.2-kh20_setup
+WizardImageFile=icecast2logo2.bmp
+WizardImageStretch=no
+VersionInfoVersion=2.3.2
+; uncomment the following line if you want your installation to run on NT 3.51 too.
+; MinVersion=4,3.51
+
+[Tasks]
+Name: "desktopicon"; Description: "Create a &desktop icon"; GroupDescription: "Additional icons:"; MinVersion: 4,4
+
+[Dirs]
+Name: "{app}\web"
+Name: "{app}\admin"
+Name: "{app}\doc"
+Name: "{app}\logs"
+Name: "{app}\examples"
+
+
+[Files]
+Source: "win_release\icecast2win.exe"; DestDir: "{app}"; Flags: ignoreversion
+Source: "console_release\icecast2_console.exe"; DestDir: "{app}"; DestName: "icecast2console.exe"; Flags: ignoreversion
+Source: "service_Release\icecastService.exe"; DestDir: "{app}"; Flags: ignoreversion
+Source: "..\examples\*"; DestDir: "{app}\examples"; Excludes: "*~"; Flags: ignoreversion
+Source: "..\doc\*"; DestDir: "{app}\doc"; Excludes: "*Makefile*"; Flags: ignoreversion
+Source: "..\web\*.xsl"; DestDir: "{app}\web"; Flags: ignoreversion
+Source: "..\web\*.html"; DestDir: "{app}\web"; Flags: ignoreversion
+Source: "..\web\images\*.png"; DestDir: "{app}\web\images"; Flags: ignoreversion
+Source: "..\web\images\*.jpg"; DestDir: "{app}\web\images"; Flags: ignoreversion
+Source: "..\web\*.css"; DestDir: "{app}\web"; Flags: ignoreversion
+Source: "..\admin\*.xsl"; DestDir: "{app}\admin"; Flags: ignoreversion
+Source: "..\admin\flashpolicy"; DestDir: "{app}\admin"; Flags: ignoreversion
+Source: "..\conf\*.dist"; DestDir: "{app}"; Flags: ignoreversion
+Source: "..\examples\icecast_shoutcast_compat.xml"; DestDir: "{app}"; DestName: "icecast.xml"; Flags: ignoreversion confirmoverwrite
+Source: ".\pthreadVSE.dll"; DestDir: "{app}"; Flags: ignoreversion
+Source: ".\iconv.dll"; DestDir: "{app}"; Flags: ignoreversion
+Source: ".\ogg.dll"; DestDir: "{app}"; Flags: ignoreversion
+Source: ".\libspeex.dll"; DestDir: "{app}"; Flags: ignoreversion
+Source: ".\libxslt.dll"; DestDir: "{app}"; Flags: ignoreversion
+Source: ".\libxml2.dll"; DestDir: "{app}"; Flags: ignoreversion
+Source: ".\libcurl.dll"; DestDir: "{app}"; Flags: ignoreversion
+Source: ".\libeay32.dll"; DestDir: "{app}"; Flags: ignoreversion
+Source: ".\ssleay32.dll"; DestDir: "{app}"; Flags: ignoreversion
+Source: ".\zlib1.dll"; DestDir: "{app}"; Flags: ignoreversion
+
+[Icons]
+
+Name: "{group}\Icecast2 Win32"; Filename: "{app}\icecast2win.exe";WorkingDir: "{app}";
+Name: "{userdesktop}\Icecast2 Win32"; Filename: "{app}\icecast2win.exe"; MinVersion: 4,4; Tasks: desktopicon;WorkingDir: "{app}";
+
+[Run]
+Filename: "{app}\icecastService.exe"; Parameters: "install ""{app}""";Description: "Install Icecast as a windows service.";Flags: postinstall
+
+[UninstallRun]
+Filename: "{app}\icecastService.exe"; Parameters: "remove"
+
+
+
+
+



More information about the commits mailing list