From 9e852dae50813b9a4225edb83946168a6ca0dc35 Mon Sep 17 00:00:00 2001 From: Philipp Schafft Date: Thu, 22 Oct 2020 13:59:31 +0000 Subject: [PATCH] Feature: Added a global client list --- src/client.c | 34 ++++++++++++++++++++++++++++++++++ src/client.h | 7 +++++++ src/main.c | 2 ++ src/source.c | 21 ++------------------- 4 files changed, 45 insertions(+), 19 deletions(-) diff --git a/src/client.c b/src/client.c index 44307e48..daa3fefc 100644 --- a/src/client.c +++ b/src/client.c @@ -101,6 +101,32 @@ const char * client_protocol_to_string(protocol_t protocol) return NULL; } +int client_compare(void *compare_arg, void *a, void *b) +{ + client_t *clienta = (client_t *) a; + client_t *clientb = (client_t *) b; + + (void)compare_arg; + + connection_t *cona = clienta->con; + connection_t *conb = clientb->con; + + if (cona->id < conb->id) return -1; + if (cona->id > conb->id) return 1; + + return 0; +} + +void client_initialize(void) +{ + global_client_list = avl_tree_new(client_compare, NULL); +} + +void client_shutdown(void) +{ + avl_tree_free(global_client_list, NULL); +} + /* create a client_t with the provided connection and parser details. Return * 0 on success, -1 if server limit has been reached. In either case a * client_t is returned just in case a message needs to be returned. Should @@ -140,6 +166,10 @@ int client_create(client_t **c_ptr, connection_t *con, http_parser_t *parser) client->write_to_client = format_generic_write_to_client; *c_ptr = client; + avl_tree_wlock(global_client_list); + avl_insert(global_client_list, client); + avl_tree_unlock(global_client_list); + listener_real = listensocket_get_listener(con->listensocket_real); listener_effective = listensocket_get_listener(con->listensocket_effective); ICECAST_LOG_DEBUG("Client %p created on connection %p (connection ID: %llu, socket real: %p \"%H\", socket effective: %p \"%H\")", @@ -267,6 +297,10 @@ void client_destroy(client_t *client) fastevent_emit(FASTEVENT_TYPE_CLIENT_DESTROY, FASTEVENT_FLAG_MODIFICATION_ALLOWED, FASTEVENT_DATATYPE_CLIENT, client); + avl_tree_wlock(global_client_list); + avl_delete(global_client_list, client, NULL); + avl_tree_unlock(global_client_list); + if (client->reuse != ICECAST_REUSE_CLOSE) { /* only reuse the client if we reached the body's EOF. */ if (client_body_eof(client) == 1) { diff --git a/src/client.h b/src/client.h index bb62274f..c440a52c 100644 --- a/src/client.h +++ b/src/client.h @@ -139,9 +139,16 @@ struct _client_tag { int (*check_buffer)(source_t *source, client_t *client); }; +avl_tree *global_client_list; + protocol_t client_protocol_from_string(const char *str); const char * client_protocol_to_string(protocol_t protocol); +void client_initialize(void); +void client_shutdown(void); + +int client_compare(void *compare_arg, void *a, void *b); // for avl. + int client_create (client_t **c_ptr, connection_t *con, http_parser_t *parser); void client_complete(client_t *client); void client_destroy(client_t *client); diff --git a/src/main.c b/src/main.c index 69d96a0a..10a54a31 100644 --- a/src/main.c +++ b/src/main.c @@ -155,6 +155,7 @@ static void initialize_subsystems(void) resolver_initialize(); config_initialize(); tls_initialize(); + client_initialize(); connection_initialize(); refbuf_initialize(); @@ -175,6 +176,7 @@ static void shutdown_subsystems(void) stats_shutdown(); connection_shutdown(); + client_shutdown(); tls_shutdown(); prng_deconfigure(); config_shutdown(); diff --git a/src/source.c b/src/source.c index ea0eba41..69af0046 100644 --- a/src/source.c +++ b/src/source.c @@ -69,7 +69,6 @@ mutex_t move_clients_mutex; /* avl tree helper */ -static int _compare_clients(void *compare_arg, void *a, void *b); static int _free_client(void *key); static void _parse_audio_info (source_t *source, const char *s); static void source_shutdown (source_t *source); @@ -100,8 +99,8 @@ source_t *source_reserve (const char *mount) if (src == NULL) break; - src->client_tree = avl_tree_new(_compare_clients, NULL); - src->pending_tree = avl_tree_new(_compare_clients, NULL); + src->client_tree = avl_tree_new(client_compare, NULL); + src->pending_tree = avl_tree_new(client_compare, NULL); src->history = playlist_new(10 /* DOCUMENT: default is max_tracks=10. */); /* make duplicates for strings or similar */ @@ -911,22 +910,6 @@ static void source_shutdown (source_t *source) } -static int _compare_clients(void *compare_arg, void *a, void *b) -{ - client_t *clienta = (client_t *) a; - client_t *clientb = (client_t *) b; - - (void)compare_arg; - - connection_t *cona = clienta->con; - connection_t *conb = clientb->con; - - if (cona->id < conb->id) return -1; - if (cona->id > conb->id) return 1; - - return 0; -} - int source_remove_client(void *key) { return 1;