[xiph-cvs] cvs commit: icecast/src admin.c refbuf.c source.c source.h

Michael Smith msmith at xiph.org
Sun Mar 30 05:52:27 PST 2003



msmith      03/03/30 08:52:27

  Modified:    src      admin.c refbuf.c source.c source.h
  Log:
  Remove locking from refbuf: we used a single global lock for all of them, which
  caused significant lock contention with many sources. Further, a single refbuf
  is never used by more than one source (and hence one thread), so the locking
  was unneeded.
  
  Fix a nasty bug in source.c:_compare_clients() - was casting a void pointer
  to the wrong type, and hence all the tree-maintaince comparisons were totally
  wrong (but due to the exact nature of the bug this wasn't causing any active
  problems until...)
  
  Add another admin command to kill a client - remove it using an id. Note that
  many clients will do auto-reconnect, so this may not be sufficient on its own,
  we might need a ban (possibly temporary) function.

Revision  Changes    Path
1.7       +37 -0     icecast/src/admin.c

Index: admin.c
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/admin.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- admin.c	15 Mar 2003 02:10:17 -0000	1.6
+++ admin.c	30 Mar 2003 13:52:27 -0000	1.7
@@ -32,6 +32,9 @@
 #define COMMAND_RAW_STATS         102
 #define COMMAND_RAW_LISTSTREAM    103
 
+/* Client management commands */
+#define COMMAND_KILL_CLIENT       201
+
 int admin_get_command(char *command)
 {
     if(!strcmp(command, "fallbacks"))
@@ -50,6 +53,8 @@
         return COMMAND_RAW_LISTSTREAM;
     else if(!strcmp(command, "moveclients"))
         return COMMAND_MOVE_CLIENTS;
+    else if(!strcmp(command, "killclient"))
+        return COMMAND_KILL_CLIENT;
     else
         return COMMAND_ERROR;
 }
@@ -62,6 +67,8 @@
 static void command_raw_stats(client_t *client);
 static void command_list_mounts(client_t *client, int formatted);
 
+static void command_kill_client(client_t *client, source_t *source);
+
 static void admin_handle_mount_request(client_t *client, source_t *source,
         int command);
 static void admin_handle_general_request(client_t *client, int command);
@@ -167,6 +174,9 @@
         case COMMAND_MOVE_CLIENTS:
             command_move_clients(client, source);
             break;
+        case COMMAND_KILL_CLIENT:
+            command_kill_client(client, source);
+            break;
         default:
             WARN0("Mount request not recognised");
             client_send_400(client, "Mount request unknown");
@@ -288,6 +298,33 @@
     html_write(client, "</table></body></html>");
 
     client_destroy(client);
+}
+
+static void command_kill_client(client_t *client, source_t *source)
+{
+    char *idtext;
+    int id;
+    client_t *listener;
+
+    COMMAND_REQUIRE(client, "id", idtext);
+
+    id = atoi(idtext);
+
+    listener = source_find_client(source, id);
+
+    if(listener != NULL) {
+        INFO1("Admin request: client %d removed", id);
+
+        /* This tags it for removal on the next iteration of the main source
+         * loop
+         */
+        listener->con->error = 1;
+
+        html_success(client, "Client removed");
+    }
+    else {
+        html_success(client, "Client not found");
+    }
 }
 
 static void command_fallback(client_t *client, source_t *source)

<p><p>1.7       +1 -10     icecast/src/refbuf.c

Index: refbuf.c
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/refbuf.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- refbuf.c	15 Mar 2003 02:10:17 -0000	1.6
+++ refbuf.c	30 Mar 2003 13:52:27 -0000	1.7
@@ -7,20 +7,14 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include "thread.h"
-
 #include "refbuf.h"
 
-mutex_t _refbuf_mutex;
-
 void refbuf_initialize(void)
 {
-    thread_mutex_create(&_refbuf_mutex);
 }
 
 void refbuf_shutdown(void)
 {
-    thread_mutex_destroy(&_refbuf_mutex);
 }
 
 refbuf_t *refbuf_new(unsigned long size)
@@ -37,20 +31,17 @@
 
 void refbuf_addref(refbuf_t *self)
 {
-    thread_mutex_lock(&_refbuf_mutex);
     self->_count++;
-    thread_mutex_unlock(&_refbuf_mutex);
 }
 
 void refbuf_release(refbuf_t *self)
 {
-    thread_mutex_lock(&_refbuf_mutex);
     self->_count--;
     if (self->_count == 0) {
         free(self->data);
         free(self);
+        return;
     }
-    thread_mutex_unlock(&_refbuf_mutex);
 }
 
 void refbuf_queue_add(refbuf_queue_t **queue, refbuf_t *refbuf)

<p><p>1.48      +25 -2     icecast/src/source.c

Index: source.c
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/source.c,v
retrieving revision 1.47
retrieving revision 1.48
diff -u -r1.47 -r1.48
--- source.c	27 Mar 2003 17:10:06 -0000	1.47
+++ source.c	30 Mar 2003 13:52:27 -0000	1.48
@@ -164,6 +164,26 @@
 
     return 1;
 }
+
+client_t *source_find_client(source_t *source, int id)
+{
+    client_t fakeclient;
+    client_t *result;
+    connection_t fakecon;
+
+    fakeclient.con = &fakecon;
+    fakeclient.con->id = id;
+
+    avl_tree_rlock(source->client_tree);
+    if(avl_get_by_key(source->client_tree, &fakeclient, (void **)&result) == 0)
+    {
+        avl_tree_unlock(source->client_tree);
+        return result;
+    }
+
+    avl_tree_unlock(source->client_tree);
+    return NULL;
+}
     
 
 void *source_main(void *arg)
@@ -657,8 +677,11 @@
 
 static int _compare_clients(void *compare_arg, void *a, void *b)
 {
-    connection_t *cona = (connection_t *)a;
-    connection_t *conb = (connection_t *)b;
+    client_t *clienta = (client_t *)a;
+    client_t *clientb = (client_t *)b;
+
+    connection_t *cona = clienta->con;
+    connection_t *conb = clientb->con;
 
     if (cona->id < conb->id) return -1;
     if (cona->id > conb->id) return 1;

<p><p>1.13      +1 -0      icecast/src/source.h

Index: source.h
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/source.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- source.h	15 Mar 2003 02:10:17 -0000	1.12
+++ source.h	30 Mar 2003 13:52:27 -0000	1.13
@@ -45,6 +45,7 @@
         http_parser_t *parser, const char *mount, format_type_t type,
         mount_proxy *mountinfo);
 source_t *source_find_mount(const char *mount);
+client_t *source_find_client(source_t *source, int id);
 int source_compare_sources(void *arg, void *a, void *b);
 int source_free_source(void *key);
 int source_remove_client(void *key);

<p><p>--- >8 ----
List archives:  http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body.  No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.



More information about the commits mailing list