[Icecast-dev] [PATCH 21/31] Add Client in connection_queue_t

Niv Sardi nsardi at smartjog.com
Fri Jul 30 07:54:43 PDT 2010


extract setup code to it's own function and use ->con from node.

Signed-off-by: Niv Sardi <nsardi at smartjog.com>
---
 src/connection.c |   85 +++++++++++++++++++++++++++++++++++++----------------
 1 files changed, 59 insertions(+), 26 deletions(-)

diff --git a/src/connection.c b/src/connection.c
index ab8dd4f..c66a240 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -86,6 +86,7 @@ typedef struct connection_queue_tag {
     connection_t *con;
     refbuf_t *refbuf;
     http_parser_t *parser;
+    client_t *client;
     struct connection_queue_tag *next;
 } connection_queue_t;
 
@@ -616,8 +617,19 @@ static connection_queue_t *_get_connection(void)
 static void _connection_node_destroy (connection_queue_t *node) {
     INFO("destroying node");
 
-    if (node->con)
-        connection_close(node->con);
+    if (node->client) {
+        client_destroy(node->client); /* destroys con, parser, refbuf */
+    } else {
+        if (node->parser) {
+            httpp_destroy(node->parser);
+        }
+        if (node->refbuf) {
+            refbuf_release(node->refbuf);
+        }
+        if (node->con) {
+            connection_close(node->con);
+        }
+    }
     free(node);
 }
 
@@ -664,9 +676,43 @@ static void *_connection_thread (void *arg)
     return NULL;
 }
 
+static int connection_client_setup (connection_queue_t *node) {
+    int err;
+
+    global_lock();
+    err = client_create (&node->client, node->con, node->parser);
+    if (err < 0) {
+        client_send_403 (node->client, "Icecast connection limit reached");
+        /* don't be too eager as this is an imposed hard limit */
+        goto out_fail;
+    }
+
+    err = -EINVAL;
+    if (sock_set_blocking (node->con->sock, 0) || sock_set_nodelay (node->con->sock)) {
+        WARN0 ("failed to set tcp options on client connection, dropping");
+        goto out_destroy_client;
+    }
+
+/* XXX(xaiki): this should be 1, but actually, it's buggy, the client is already up and all.. */
+    err = -ENOENT;
+    if (node->con->con_timeout <= time(NULL)) {
+        WARN("there might be a bug if you see this");
+        goto out_destroy_client;
+    }
+
+    global_unlock();
+
+    return 0;
+
+out_destroy_client:
+    client_destroy (node->client);
+out_fail:
+    global_unlock();
+    return err;
+}
+
 static int _connection_process (connection_queue_t *node) {
     ice_config_t *config;
-    client_t *client = NULL;
     listener_t *listener;
     refbuf_t *header;
     http_parser_t *parser = NULL;
@@ -713,50 +759,37 @@ static int _connection_process (connection_queue_t *node) {
         }
     }
 
-    global_lock();
-    err = client_create (&client, node->con, parser);
-    if (err < 0)
-    {
-        global_unlock();
-        client_send_403 (client, "Icecast connection limit reached");
-        /* don't be too eager as this is an imposed hard limit */
-        return err;
-    }
-
-    if (sock_set_blocking (client->con->sock, 0) || sock_set_nodelay (client->con->sock))
-    {
-        global_unlock();
-        WARN0 ("failed to set tcp options on client connection, dropping");
-        client_destroy (client);
-        return -1;
+    if (! node->client) {
+        err = connection_client_setup (node);
+        if (err < 0)
+            return err;
     }
 
     header->len -= hdrsize;
     if (header->len) {
         memmove(header->data, header->data + hdrsize, header->len);
-        client_set_queue (client, header);
+        client_set_queue (node->client, header);
     }
     refbuf_release(header);
 
     config = config_get_config();
-    listener = config_get_listen_sock (config, client->con);
+    listener = config_get_listen_sock (config, node->con);
 
     if (listener)
     {
         if (listener->shoutcast_compat)
             shoutcast = 1;
         if (listener->ssl && ssl_ok)
-            connection_uses_ssl (client->con);
+            connection_uses_ssl (node->con);
         if (listener->shoutcast_mount)
             shoutcast_mount = strdup (listener->shoutcast_mount);
     }
-    global_unlock();
     config_release_config();
 
 /* XXX(xaiki): this should be 1, but actually, it's buggy, the client is already up and all.. */
-    if (client->con->con_timeout <= time(NULL)) {
+    if (node->con->con_timeout <= time(NULL)) {
         WARN("there might be a bug if you see this");
-        client_destroy (client);
+        client_destroy (node->client);
         return -1;
     }
 
@@ -766,7 +799,7 @@ static int _connection_process (connection_queue_t *node) {
         _handle_shoutcast_compatible (shoutcast, shoutcast_mount);
         return 0;
     }
-    return _handle_client (client);
+    return _handle_client (node->client);
 }
 
 void connection_accept_loop (void)
-- 
1.7.1



More information about the Icecast-dev mailing list