From 923fecd242a7d65e6d4922aa9ffcee885e49506d Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Fri, 14 Feb 2025 09:09:00 -0400 Subject: [PATCH] MT#55283 split up reserve_port Change-Id: I194f9661c890a3fe4f4814fc84c747baa2ba0f11 --- daemon/media_socket.c | 53 ++++++++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 23 deletions(-) diff --git a/daemon/media_socket.c b/daemon/media_socket.c index 694ebc41f..adb01d2a7 100644 --- a/daemon/media_socket.c +++ b/daemon/media_socket.c @@ -684,6 +684,32 @@ int is_local_endpoint(const struct intf_address *addr, unsigned int port) { static void release_reserved_port(struct port_pool *pp, ports_q *); +static void reserve_additional_port_links(ports_q *ret, struct port_pool *pp, unsigned int port) { + for (__auto_type l = pp->overlaps.head; l; l = l->next) { + __auto_type opp = l->data; + + if (port < opp->min || port > opp->max) + continue; + + LOCK(&opp->free_list_lock); + __auto_type link = free_ports_link(opp, port); + if (!link) + goto bail; + // move link from free list to output + t_queue_unlink(&opp->free_ports_q, link); + free_ports_link(opp, port) = NULL; + t_queue_push_tail_link(ret, link); + } + + return; + +bail: + // Oops. Some spec didn't have the port available. Probably a race condition. + // Return everything to its place and report failure by resetting the output + // list to empty. + release_reserved_port(pp, ret); +} + /** * This function just (globally) reserves a port number, it doesn't provide any binding/unbinding. * Returns linked list if successful, or NULL if failed. @@ -692,41 +718,22 @@ static ports_q reserve_port(struct port_pool *pp, unsigned int port) { ports_q ret = TYPED_GQUEUE_INIT; if (port < pp->min || port > pp->max) - return ret; + return ret; // empty result { LOCK(&pp->free_list_lock); __auto_type link = free_ports_link(pp, port); if (!link) - return ret; + return ret; // empty result // move link from free list to output t_queue_unlink(&pp->free_ports_q, link); free_ports_link(pp, port) = NULL; t_queue_push_tail_link(&ret, link); } - for (__auto_type l = pp->overlaps.head; l; l = l->next) { - __auto_type opp = l->data; - - if (port < opp->min || port > opp->max) - continue; - - LOCK(&opp->free_list_lock); - __auto_type link = free_ports_link(opp, port); - if (!link) - goto bail; - // move link from free list to output - t_queue_unlink(&opp->free_ports_q, link); - free_ports_link(opp, port) = NULL; - t_queue_push_tail_link(&ret, link); - } - - return ret; + reserve_additional_port_links(&ret, pp, port); + // reverts `ret` to empty result on failure -bail: - // Oops. Some spec didn't have the port available. Probably a race condition. - // Return everything to its place and report failure. - release_reserved_port(pp, &ret); return ret; } /**