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

karl at svn.xiph.org karl at svn.xiph.org
Mon Jul 21 19:37:32 PDT 2008


Author: karl
Date: 2008-07-21 19:37:32 -0700 (Mon, 21 Jul 2008)
New Revision: 15124

Modified:
   icecast/trunk/icecast/src/fserve.c
Log:
Make fserve thread start up only when required. In most cases this thread is
just in a sleep loop which means most clients getting to it have to wait. We
now just start the thread when there is work to do.  There is also some small
cleanup for the off_t type usage as well.


Modified: icecast/trunk/icecast/src/fserve.c
===================================================================
--- icecast/trunk/icecast/src/fserve.c	2008-07-22 02:24:30 UTC (rev 15123)
+++ icecast/trunk/icecast/src/fserve.c	2008-07-22 02:37:32 UTC (rev 15124)
@@ -29,12 +29,14 @@
 #include <unistd.h>
 #include <sys/time.h>
 #include <sys/socket.h>
+#define SCN_OFF_T SCNdMAX
+#define PRI_OFF_T PRIdMAX
 #else
 #include <winsock2.h>
 #include <windows.h>
 #define fseeko fseek
-#define PRIdMAX "ld"
-#define SCNdMAX "ld"
+#define SCN_OFF_T "ld"
+#define PRI_OFF_T "ld"
 #define snprintf _snprintf
 #define strncasecmp _strnicmp
 #define S_ISREG(mode)  ((mode) & _S_IFREG)
@@ -70,8 +72,7 @@
 static mutex_t pending_lock;
 static avl_tree *mimetypes = NULL;
 
-static thread_type *fserv_thread;
-static int run_fserv = 0;
+static volatile int run_fserv = 0;
 static unsigned int fserve_clients;
 static int client_tree_changed=0;
 
@@ -101,23 +102,34 @@
     fserve_recheck_mime_types (config);
     config_release_config();
 
-    run_fserv = 1;
     stats_event (NULL, "file_connections", "0");
-
-    fserv_thread = thread_create("File Serving Thread", 
-            fserv_thread_function, NULL, THREAD_ATTACHED);
+    INFO0("file serving started");
 }
 
 void fserve_shutdown(void)
 {
-    if(!run_fserv)
-        return;
+    thread_mutex_lock (&pending_lock);
+    run_fserv = 0;
+    while (pending_list)
+    {
+        fserve_t *to_go = (fserve_t *)pending_list;
+        pending_list = to_go->next;
 
-    run_fserv = 0;
-    thread_join(fserv_thread);
-    INFO0("file serving thread stopped");
+        fserve_client_destroy (to_go);
+    }
+    while (active_list)
+    {
+        fserve_t *to_go = active_list;
+        active_list = to_go->next;
+        fserve_client_destroy (to_go);
+    }
+
     if (mimetypes)
         avl_tree_free (mimetypes, _delete_mapping);
+
+    thread_mutex_unlock (&pending_lock);
+    thread_mutex_destroy (&pending_lock);
+    INFO0("file serving stopped");
 }
 
 #ifdef HAVE_POLL
@@ -142,7 +154,12 @@
         }
     }
     if (!ufds)
-        thread_sleep(200000);
+    {
+        thread_mutex_lock (&pending_lock);
+        run_fserv = 0;
+        thread_mutex_unlock (&pending_lock);
+        return -1;
+    }
     else if (poll(ufds, fserve_clients, 200) > 0)
     {
         /* mark any clients that are ready */
@@ -178,7 +195,12 @@
     }
     /* hack for windows, select needs at least 1 descriptor */
     if (fd_max == SOCK_ERROR)
-        thread_sleep (200000);
+    {
+        thread_mutex_lock (&pending_lock);
+        run_fserv = 0;
+        thread_mutex_unlock (&pending_lock);
+        return -1;
+    }
     else
     {
         struct timeval tv;
@@ -204,8 +226,10 @@
 }
 #endif
 
-static void wait_for_fds(void) {
+static int wait_for_fds(void)
+{
     fserve_t *fclient;
+    int ret;
 
     while (run_fserv)
     {
@@ -228,9 +252,11 @@
             thread_mutex_unlock (&pending_lock);
         }
         /* drop out of here if someone is ready */
-        if (fserve_client_waiting())
-            break;
+        ret = fserve_client_waiting();
+        if (ret)
+            return ret;
     }
+    return -1;
 }
 
 static void *fserv_thread_function(void *arg)
@@ -238,9 +264,10 @@
     fserve_t *fclient, **trail;
     size_t bytes;
 
-    INFO0("file serving thread started");
-    while (run_fserv) {
-        wait_for_fds();
+    while (1)
+    {
+        if (wait_for_fds() < 0)
+            break;
 
         fclient = active_list;
         trail = &active_list;
@@ -515,7 +542,7 @@
     if (range != NULL) {
         ret = 0;
         if (strncasecmp (range, "bytes=", 6) == 0)
-            ret = sscanf (range+6, "%" SCNdMAX "-", &rangenumber);
+            ret = sscanf (range+6, "%" SCN_OFF_T "-", &rangenumber);
 
         if (ret != 1) {
             /* format not correct, so lets just assume
@@ -557,9 +584,9 @@
                     "HTTP/1.1 206 Partial Content\r\n"
                     "Date: %s\r\n"
                     "Accept-Ranges: bytes\r\n"
-                    "Content-Length: %" PRIdMAX "\r\n"
-                    "Content-Range: bytes %" PRIdMAX \
-                    "-%" PRIdMAX "/%" PRIdMAX "\r\n"
+                    "Content-Length: %" PRI_OFF_T "\r\n"
+                    "Content-Range: bytes %" PRI_OFF_T \
+                    "-%" PRI_OFF_T "/%" PRI_OFF_T "\r\n"
                     "Content-Type: %s\r\n\r\n",
                     currenttime,
                     new_content_len,
@@ -583,7 +610,7 @@
         bytes = snprintf (httpclient->refbuf->data, BUFSIZE,
             "HTTP/1.0 200 OK\r\n"
             "Accept-Ranges: bytes\r\n"
-            "Content-Length: %" PRIdMAX "\r\n"
+            "Content-Length: %" PRI_OFF_T "\r\n"
             "Content-Type: %s\r\n\r\n",
             content_length,
             type);
@@ -607,6 +634,24 @@
 }
 
 
+/* Routine to actually add pre-configured client structure to pending list and
+ * then to start off the file serving thread if it is not already running
+ */
+static void fserve_add_pending (fserve_t *fclient)
+{
+    thread_mutex_lock (&pending_lock);
+    fclient->next = (fserve_t *)pending_list;
+    pending_list = fclient;
+    if (run_fserv == 0)
+    {
+        run_fserv = 1;
+        DEBUG0 ("fserve handler waking up");
+        thread_create("File Serving Thread", fserv_thread_function, NULL, THREAD_DETACHED);
+    }
+    thread_mutex_unlock (&pending_lock);
+}
+
+
 /* Add client to fserve thread, client needs to have refbuf set and filled
  * but may provide a NULL file if no data needs to be read
  */
@@ -623,12 +668,8 @@
     fclient->file = file;
     fclient->client = client;
     fclient->ready = 0;
+    fserve_add_pending (fclient);
 
-    thread_mutex_lock (&pending_lock);
-    fclient->next = (fserve_t *)pending_list;
-    pending_list = fclient;
-    thread_mutex_unlock (&pending_lock);
-
     return 0;
 }
 
@@ -652,10 +693,7 @@
     fclient->callback = callback;
     fclient->arg = arg;
 
-    thread_mutex_lock (&pending_lock);
-    fclient->next = (fserve_t *)pending_list;
-    pending_list = fclient;
-    thread_mutex_unlock (&pending_lock);
+    fserve_add_pending (fclient);
 }
 
 



More information about the commits mailing list