From de6346a5bf01b196a6135bff2b998615d4d8681b Mon Sep 17 00:00:00 2001 From: Andreas Eversberg Date: Sat, 28 Jul 2012 08:21:47 +0200 Subject: [PATCH 1/1] Changed bridge structure to hold 1..n members instead of only 1..2 --- port.cpp | 66 +++++++++++++++++++++++++++++++--------------------------------- port.h | 8 ++++++-- 2 files changed, 38 insertions(+), 36 deletions(-) diff --git a/port.cpp b/port.cpp index 8fed914..a05deca 100644 --- a/port.cpp +++ b/port.cpp @@ -1177,20 +1177,21 @@ static void remove_bridge(struct port_bridge *bridge, class Port *port) struct port_bridge **temp = &p_bridge_first; while (*temp) { if (*temp == bridge) { - int remove = 0; - - /* Remove us from bridge. If bridge is empty, remove it completely. */ - if (bridge->sunrise == port) { - bridge->sunrise = NULL; - if (!bridge->sunset) - remove = 1; - } - if (bridge->sunset == port) { - bridge->sunset = NULL; - if (!bridge->sunrise) - remove = 1; + struct port_bridge_member **memberp = &bridge->first, *member; + + /* loop until we are found */ + while(*memberp) { + if ((*memberp)->port == port) { + member = *memberp; + *memberp = member->next; + FREE(member, sizeof(struct port_bridge_member)); + memuse--; + break; + } + memberp = &((*memberp)->next); } - if (remove) { + /* if bridge is empty, remove it */ + if (bridge->first == NULL) { PDEBUG(DEBUG_PORT, "Remove bridge %u\n", bridge->bridge_id); *temp = bridge->next; FREE(bridge, sizeof(struct port_bridge)); @@ -1205,6 +1206,8 @@ static void remove_bridge(struct port_bridge *bridge, class Port *port) void Port::bridge(unsigned int bridge_id) { + struct port_bridge_member **memberp; + /* Remove bridge, if we leave bridge or if we join a different bridge. */ if (p_bridge && bridge_id != p_bridge->bridge_id) { PDEBUG(DEBUG_PORT, "Remove port %u from bridge %u, because out new bridge is %u\n", p_serial, p_bridge->bridge_id, bridge_id); @@ -1237,7 +1240,6 @@ void Port::bridge(unsigned int bridge_id) p_bridge = (struct port_bridge *) MALLOC(sizeof(struct port_bridge)); memuse++; p_bridge->bridge_id = bridge_id; - p_bridge->sunrise = this; /* attach bridge instance to list */ while (*temp) @@ -1246,22 +1248,18 @@ void Port::bridge(unsigned int bridge_id) PDEBUG(DEBUG_PORT, "Port %d creating not existing bridge %u.\n", p_serial, p_bridge->bridge_id); } - /* already joined */ - if (p_bridge->sunrise == this || p_bridge->sunset == this) - return; - - /* join bridge */ - if (!p_bridge->sunrise) { - p_bridge->sunrise = this; - return; - } - if (!p_bridge->sunset) { - p_bridge->sunset = this; - return; + /* attach to bridge */ + memberp = &p_bridge->first; + while(*memberp) { + if ((*memberp)->port == this) { + /* already joined */ + return; + } + memberp = &((*memberp)->next); } - - PERROR("Bridge ID %u cannot be joined by port %u, because it is already occupied by ports %u and %u.\n", p_bridge->bridge_id, p_serial, p_bridge->sunrise->p_serial, p_bridge->sunset->p_serial); - p_bridge = NULL; + *memberp = (struct port_bridge_member *) MALLOC(sizeof(struct port_bridge_member)); + memuse++; + (*memberp)->port = this; } class Port *Port::bridge_remote(void) @@ -1269,12 +1267,12 @@ class Port *Port::bridge_remote(void) class Port *remote = NULL; /* get remote port from bridge */ - if (!p_bridge) + if (!p_bridge || !p_bridge->first || !p_bridge->first->next) return NULL; - if (p_bridge->sunrise == this) - remote = p_bridge->sunset; - if (p_bridge->sunset == this) - remote = p_bridge->sunrise; + if (p_bridge->first->port == this) + remote = p_bridge->first->next->port; + if (p_bridge->first->next->port == this) + remote = p_bridge->first->port; return remote; } diff --git a/port.h b/port.h index 4833ad7..90b7239 100644 --- a/port.h +++ b/port.h @@ -149,12 +149,16 @@ struct port_settings { int no_seconds; }; +struct port_bridge_member { + struct port_bridge_member *next; + class Port *port; +}; + /* port bridge instance */ struct port_bridge { struct port_bridge *next; /* next bridge node */ unsigned int bridge_id; /* unique ID to identify bridge */ - class Port *sunrise; /* one side of the bridge */ - class Port *sunset; /* other side of the bridge */ + struct port_bridge_member *first; /* list of ports that are bridged */ }; extern struct port_bridge *p_bridge_first; -- 2.13.6