MT#55283 split up reserve_port

Change-Id: I194f9661c890a3fe4f4814fc84c747baa2ba0f11
pull/1918/head
Richard Fuchs 3 months ago
parent 806d272f89
commit 923fecd242

@ -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 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. * This function just (globally) reserves a port number, it doesn't provide any binding/unbinding.
* Returns linked list if successful, or NULL if failed. * 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; ports_q ret = TYPED_GQUEUE_INIT;
if (port < pp->min || port > pp->max) if (port < pp->min || port > pp->max)
return ret; return ret; // empty result
{ {
LOCK(&pp->free_list_lock); LOCK(&pp->free_list_lock);
__auto_type link = free_ports_link(pp, port); __auto_type link = free_ports_link(pp, port);
if (!link) if (!link)
return ret; return ret; // empty result
// move link from free list to output // move link from free list to output
t_queue_unlink(&pp->free_ports_q, link); t_queue_unlink(&pp->free_ports_q, link);
free_ports_link(pp, port) = NULL; free_ports_link(pp, port) = NULL;
t_queue_push_tail_link(&ret, link); t_queue_push_tail_link(&ret, link);
} }
for (__auto_type l = pp->overlaps.head; l; l = l->next) { reserve_additional_port_links(&ret, pp, port);
__auto_type opp = l->data; // reverts `ret` to empty result on failure
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;
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; return ret;
} }
/** /**

Loading…
Cancel
Save