[xiph-commits] r8198 - icecast/branches/kh/icecast/src

karl at motherfish-iii.xiph.org karl at motherfish-iii.xiph.org
Sun Nov 14 12:29:10 PST 2004


Author: karl
Date: 2004-11-14 12:29:10 -0800 (Sun, 14 Nov 2004)
New Revision: 8198

Modified:
   icecast/branches/kh/icecast/src/admin.c
   icecast/branches/kh/icecast/src/auth.c
   icecast/branches/kh/icecast/src/connection.c
   icecast/branches/kh/icecast/src/format.c
   icecast/branches/kh/icecast/src/format.h
   icecast/branches/kh/icecast/src/fserve.c
   icecast/branches/kh/icecast/src/fserve.h
   icecast/branches/kh/icecast/src/slave.c
   icecast/branches/kh/icecast/src/slave.h
   icecast/branches/kh/icecast/src/source.c
   icecast/branches/kh/icecast/src/source.h
   icecast/branches/kh/icecast/src/stats.c
   icecast/branches/kh/icecast/src/stats.h
Log:
implement fallback to file, also small updates to stats handling


Modified: icecast/branches/kh/icecast/src/admin.c
===================================================================
--- icecast/branches/kh/icecast/src/admin.c	2004-11-14 16:49:06 UTC (rev 8197)
+++ icecast/branches/kh/icecast/src/admin.c	2004-11-14 20:29:10 UTC (rev 8198)
@@ -916,7 +916,7 @@
 
     DEBUG0("Stats request, sending xml stats");
 
-    stats_get_xml(&doc);
+    stats_get_xml(&doc, 1);
     admin_send_response(doc, client, response, STATS_TRANSFORMED_REQUEST);
     xmlFreeDoc(doc);
     client_destroy(client);

Modified: icecast/branches/kh/icecast/src/auth.c
===================================================================
--- icecast/branches/kh/icecast/src/auth.c	2004-11-14 16:49:06 UTC (rev 8197)
+++ icecast/branches/kh/icecast/src/auth.c	2004-11-14 20:29:10 UTC (rev 8198)
@@ -155,7 +155,7 @@
 {
     int ret = -1;
     source_t *source;
-    avl_tree_unlock (global.source_tree);
+    avl_tree_rlock (global.source_tree);
     source = source_find_mount (mount);
     if (source)
     {

Modified: icecast/branches/kh/icecast/src/connection.c
===================================================================
--- icecast/branches/kh/icecast/src/connection.c	2004-11-14 16:49:06 UTC (rev 8197)
+++ icecast/branches/kh/icecast/src/connection.c	2004-11-14 20:29:10 UTC (rev 8198)
@@ -467,7 +467,7 @@
          * because we can't use this client to return an error code/message,
          * so we only do this once we know we're going to accept the source.
          */
-        if (source->client == NULL)
+        if (source->client == NULL && source->con)
             source->client = client_create (source->con, source->parser);
 
         source_update_settings (config, source);

Modified: icecast/branches/kh/icecast/src/format.c
===================================================================
--- icecast/branches/kh/icecast/src/format.c	2004-11-14 16:49:06 UTC (rev 8197)
+++ icecast/branches/kh/icecast/src/format.c	2004-11-14 20:29:10 UTC (rev 8198)
@@ -120,7 +120,7 @@
 /* wrapper for the per-format write to client routine. Here we populate
  * the refbuf before calling it
  */
-static int format_intro_write_to_client (source_t *source, client_t *client)
+int format_intro_write_to_client (source_t *source, client_t *client)
 {
     refbuf_t *refbuf = client->refbuf;
 
@@ -128,8 +128,17 @@
     {
         if (get_intro_data (source->intro_file, client) == 0)
         {
-            client_set_queue (client, source->stream_data_tail);
-            client->write_to_client = source->format->write_buf_to_client;
+            if (source->stream_data_tail)
+            {
+                /* move client to stream */
+                client_set_queue (client, source->stream_data_tail);
+                client->write_to_client = source->format->write_buf_to_client;
+            }
+            else
+            {
+                /* replay intro file */
+                client->intro_offset = 0;
+            }
             return 0;
         }
         client->pos = 0;

Modified: icecast/branches/kh/icecast/src/format.h
===================================================================
--- icecast/branches/kh/icecast/src/format.h	2004-11-14 16:49:06 UTC (rev 8197)
+++ icecast/branches/kh/icecast/src/format.h	2004-11-14 20:29:10 UTC (rev 8198)
@@ -63,6 +63,7 @@
 void format_send_general_headers(format_plugin_t *format, 
         struct source_tag *source, client_t *client);
 int format_http_write_to_client (struct source_tag *source, client_t *client);
+int format_intro_write_to_client (struct source_tag *source, client_t *client);
 void format_initialise();
 
 #endif  /* __FORMAT_H__ */

Modified: icecast/branches/kh/icecast/src/fserve.c
===================================================================
--- icecast/branches/kh/icecast/src/fserve.c	2004-11-14 16:49:06 UTC (rev 8197)
+++ icecast/branches/kh/icecast/src/fserve.c	2004-11-14 20:29:10 UTC (rev 8198)
@@ -307,7 +307,7 @@
     return NULL;
 }
 
-static char *fserve_content_type(char *path)
+const char *fserve_content_type (char *path)
 {
     char *ext = util_get_extension(path);
     mime_type exttype = {ext, NULL};

Modified: icecast/branches/kh/icecast/src/fserve.h
===================================================================
--- icecast/branches/kh/icecast/src/fserve.h	2004-11-14 16:49:06 UTC (rev 8197)
+++ icecast/branches/kh/icecast/src/fserve.h	2004-11-14 20:29:10 UTC (rev 8198)
@@ -27,6 +27,7 @@
 void fserve_initialize(void);
 void fserve_shutdown(void);
 int fserve_client_create(client_t *httpclient, char *path);
+const char *fserve_content_type (char *path);
 
 
 #endif

Modified: icecast/branches/kh/icecast/src/slave.c
===================================================================
--- icecast/branches/kh/icecast/src/slave.c	2004-11-14 16:49:06 UTC (rev 8197)
+++ icecast/branches/kh/icecast/src/slave.c	2004-11-14 20:29:10 UTC (rev 8198)
@@ -123,6 +123,12 @@
     rescan_relays = 1;
 }
 
+/* kick off a rescan but force a recheck of the mounts afterwards */
+void slave_rebuild (void)
+{
+    update_settings = 1;
+    slave_rescan ();
+}
 
 void slave_initialize(void)
 {
@@ -301,7 +307,7 @@
         {
             /* only keep refreshing YP entries for inactive on-demand relays */
             yp_remove (relay->localmount);
-            source_recheck_mounts();
+            update_settings = 1;
         }
         /* initiate an immediate relay cleanup run */
         relay->cleanup = 1;
@@ -667,6 +673,7 @@
     config = config_get_config();
     update_master_as_slave (config);
     config_release_config();
+    source_recheck_mounts();
 
     while (slave_running)
     {

Modified: icecast/branches/kh/icecast/src/slave.h
===================================================================
--- icecast/branches/kh/icecast/src/slave.h	2004-11-14 16:49:06 UTC (rev 8197)
+++ icecast/branches/kh/icecast/src/slave.h	2004-11-14 20:29:10 UTC (rev 8198)
@@ -45,6 +45,7 @@
 void slave_shutdown(void);
 void slave_recheck (void);
 void slave_rescan (void);
+void slave_rebuild (void);
 int slave_redirect (const char *mountpoint, struct _client_tag *client);
 void slave_host_add (struct _client_tag *client, const char *header);
 void slave_host_remove (struct _client_tag *client);

Modified: icecast/branches/kh/icecast/src/source.c
===================================================================
--- icecast/branches/kh/icecast/src/source.c	2004-11-14 16:49:06 UTC (rev 8197)
+++ icecast/branches/kh/icecast/src/source.c	2004-11-14 20:29:10 UTC (rev 8198)
@@ -48,6 +48,7 @@
 #include "util.h"
 #include "source.h"
 #include "format.h"
+#include "fserve.h"
 #include "auth.h"
 
 #undef CATMODULE
@@ -510,6 +511,7 @@
 static void process_listeners (source_t *source, int fast_clients_only, int deletion_expected)
 {
     client_t *sentinel = NULL, *client, **client_p;
+    unsigned int listeners = source->listeners;
 
     if (fast_clients_only)
     {
@@ -558,6 +560,14 @@
             client = client->next;
         }
     }
+    /* has the listener count changed */
+    if (source->listeners != listeners)
+    {
+        INFO2("listener count on %s now %d", source->mount, source->listeners);
+        stats_event_args (source->mount, "listeners", "%d", source->listeners);
+        if (source->listeners == 0 && source->on_demand)
+            source->running = 0;
+    }
 }
 
 
@@ -572,7 +582,7 @@
 
     while (global.running == ICE_RUNNING && source->running)
     {
-        int fds;
+        int fds = 0;
         time_t current = time(NULL);
         int delay = 200;
 
@@ -591,7 +601,13 @@
 
         thread_mutex_unlock (&source->lock);
 
-        fds = util_timed_wait_for_fd (source->con->sock, delay);
+        if (source->con)
+            fds = util_timed_wait_for_fd (source->con->sock, delay);
+        else
+        {
+            thread_sleep (delay*1000);
+            source->last_read = current;
+        }
 
         /* take the lock */
         thread_mutex_lock (&source->lock);
@@ -723,7 +739,8 @@
     stats_event_inc (NULL, "source_total_connections");
     stats_event (source->mount, "type", source->format->format_description);
 
-    sock_set_blocking (source->con->sock, SOCK_NONBLOCK);
+    if (source->con)
+        sock_set_blocking (source->con->sock, SOCK_NONBLOCK);
 
     DEBUG0("Source creation complete");
     source->last_read = time (NULL);
@@ -761,7 +778,7 @@
 
         avl_tree_unlock(global.source_tree);
     }
-    source_recheck_mounts();
+    slave_rebuild ();
     thread_mutex_lock (&source->lock);
     if (source->yp_public)
         yp_add (source);
@@ -949,12 +966,22 @@
         client_t *to_go = client;
 
         client = client->next;
+        /*  trap from when clients have been moved */
         if (to_go->write_to_client == NULL)
         {
-            /* The client may of been moved here when we were an 
-             * inactive on-demand relay */
-            to_go->write_to_client = source->format->write_buf_to_client;
-            client_set_queue (to_go, source->stream_data_tail);
+            /* trap for client moved to fallback file */
+            if (source->file_only)
+            {
+                to_go->write_to_client = format_intro_write_to_client;
+                client_set_queue (to_go, refbuf_new(4096));
+                to_go->intro_offset = 0;
+                to_go->pos = 4096;
+            }
+            else
+            {
+                to_go->write_to_client = source->format->write_buf_to_client;
+                client_set_queue (to_go, source->stream_data_tail);
+            }
         }
 
         to_go->next = source->active_clients;
@@ -977,14 +1004,8 @@
 
 void source_main(source_t *source)
 {
-    long bytes;
-    int listeners = 0;
-
     source_init (source);
 
-    bytes = 0;
-    listeners = 0;
-
     while (global.running == ICE_RUNNING && source->running)
     {
         int remove_from_q;
@@ -1004,16 +1025,6 @@
 
         process_listeners (source, 0, remove_from_q);
 
-        /* has the listener count changed */
-        if (source->listeners != listeners)
-        {
-            INFO2("listener count on %s now %d", source->mount, source->listeners);
-            stats_event_args (source->mount, "listeners", "%d", source->listeners);
-            if (source->listeners == 0 && source->on_demand)
-                source->running = 0;
-            listeners = source->listeners;
-        }
-
         /* lets reduce the queue, any lagging clients should of been
          * terminated by now
          */
@@ -1250,7 +1261,10 @@
     {
         if (strcmp (mountproxy->mountname, source->mount) == 0)
         {
-            source_apply_mount (source, mountproxy);
+            if (source->file_only)
+                WARN1 ("skipping fallback to file \"%s\"", source->mount);
+            else
+                source_apply_mount (source, mountproxy);
             break;
         }
         mountproxy = mountproxy->next;
@@ -1275,6 +1289,8 @@
     else
         stats_event_hidden (source->mount, NULL, 0);
 
+    if (source->file_only)
+        stats_event (source->mount, "file_only", "1");
     if (source->max_listeners == -1)
         stats_event (source->mount, "max_listeners", "unlimited");
     else
@@ -1322,10 +1338,13 @@
 {
     source_t *source = arg;
     const char ok_msg[] = "HTTP/1.0 200 OK\r\n\r\n";
-    int bytes;
+    int bytes = sizeof (ok_msg)-1;
 
-    source->client->respcode = 200;
-    bytes = sock_write_bytes (source->client->con->sock, ok_msg, sizeof (ok_msg)-1);
+    if (source->client)
+    {
+        source->client->respcode = 200;
+        bytes = sock_write_bytes (source->client->con->sock, ok_msg, sizeof (ok_msg)-1);
+    }
     if (bytes < (int)sizeof (ok_msg)-1)
     {
         global_lock();
@@ -1336,13 +1355,15 @@
     }
     else
     {
-        source->client->con->sent_bytes += bytes;
+        if (source->client)
+            source->client->con->sent_bytes += bytes;
 
         stats_event_inc(NULL, "source_client_connections");
         stats_event (source->mount, "listeners", "0");
         source_main (source);
         source_free_source (source);
-        source_recheck_mounts();
+
+        slave_rebuild ();
     }
     return NULL;
 }
@@ -1382,6 +1403,66 @@
 }
 #endif
 
+
+static void *source_fallback_file (void *arg)
+{
+    char *mount = arg;
+    const char *type;
+    char *path;
+    unsigned int len;
+    FILE *file = NULL;
+    source_t *source = NULL;
+    ice_config_t *config;
+
+    do
+    {
+        if (mount == NULL || mount[0] != '/')
+            break;
+        config = config_get_config();
+        len  = strlen (config->webroot_dir) + strlen (mount) + 1;
+        path = malloc (len);
+        if (path)
+            snprintf (path, len, "%s%s", config->webroot_dir, mount);
+        
+        config_release_config ();
+        if (path == NULL)
+            break;
+
+        file = fopen (path, "rb");
+        if (file == NULL)
+        {
+            DEBUG1 ("unable to open file \"%s\"", path);
+            free (path);
+            break;
+        }
+        free (path);
+        source = source_reserve (mount);
+        if (source == NULL)
+        {
+            DEBUG1 ("mountpoint \"%s\" already reserved", mount);
+            break;
+        }
+        type = fserve_content_type (mount);
+        source->parser = httpp_create_parser();
+        httpp_initialize (source->parser, NULL);
+        httpp_setvar (source->parser, "content-type", type);
+        source->hidden = 1;
+        source->file_only = 1;
+        source->yp_prevent = 1;
+        source->intro_file = file;
+        file = NULL;
+
+        if (connection_complete_source (source) < 0)
+            break;
+        source_client_thread (source);
+    } while (0);
+    if (file)
+        fclose (file);
+    free (mount);
+    return NULL;
+}
+
+
 /* rescan the mount list, so that xsl files are updated to show
  * unconnected but active fallback mountpoints
  */
@@ -1429,6 +1510,16 @@
                     stats_event_args (mount->mountname, "max_listeners", "%d", mount->max_listeners);
             }
         }
+        /* check for fallback to file */
+        if (global.running == ICE_RUNNING && mount->fallback_mount)
+        {
+            source_t *fallback = source_find_mount (mount->fallback_mount);
+            if (fallback == NULL)
+            {
+                thread_create ("Fallback file thread", source_fallback_file,
+                        strdup (mount->fallback_mount), THREAD_DETACHED);
+            }
+        }
 
         mount = mount->next;
     }

Modified: icecast/branches/kh/icecast/src/source.h
===================================================================
--- icecast/branches/kh/icecast/src/source.h	2004-11-14 16:49:06 UTC (rev 8197)
+++ icecast/branches/kh/icecast/src/source.h	2004-11-14 20:29:10 UTC (rev 8198)
@@ -74,6 +74,7 @@
     int on_demand;
     int on_demand_req;
     int hidden;
+    int file_only;
     int recheck_settings;
 
     time_t last_read;

Modified: icecast/branches/kh/icecast/src/stats.c
===================================================================
--- icecast/branches/kh/icecast/src/stats.c	2004-11-14 16:49:06 UTC (rev 8197)
+++ icecast/branches/kh/icecast/src/stats.c	2004-11-14 20:29:10 UTC (rev 8198)
@@ -843,14 +843,14 @@
 {
     xmlDocPtr doc;
 
-    stats_get_xml(&doc);
+    stats_get_xml(&doc, 0);
 
     xslt_transform(doc, xslpath, client);
 
     xmlFreeDoc(doc);
 }
 
-void stats_get_xml(xmlDocPtr *doc)
+void stats_get_xml(xmlDocPtr *doc, int show_hidden)
 {
     stats_event_t *event;
     stats_event_t *queue;
@@ -869,7 +869,7 @@
     event = _get_event_from_queue(&queue);
     while (event)
     {
-        if (event->hidden == 0)
+        if (event->hidden <= show_hidden)
         {
             xmlChar *name, *value;
             name = xmlEncodeEntitiesReentrant (*doc, event->name);

Modified: icecast/branches/kh/icecast/src/stats.h
===================================================================
--- icecast/branches/kh/icecast/src/stats.h	2004-11-14 16:49:06 UTC (rev 8197)
+++ icecast/branches/kh/icecast/src/stats.h	2004-11-14 20:29:10 UTC (rev 8198)
@@ -93,7 +93,7 @@
 
 void stats_transform_xslt(client_t *client, char *xslpath);
 void stats_sendxml(client_t *client);
-void stats_get_xml(xmlDocPtr *doc);
+void stats_get_xml(xmlDocPtr *doc, int show_hidden);
 char *stats_get_value(char *source, char *name);
 
 #endif  /* __STATS_H__ */



More information about the commits mailing list