[PATCH 21/31] Add Client in connection_queue_t
Niv Sardi <[email protected]>
| Newsgroups | gmane.comp.audio.icecast.devel |
|---|---|
| Message-ID | <[email protected]> |
extract setup code to it's own function and use ->con from node. Signed-off-by: Niv Sardi <[email protected]> --- 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