From 4bd04c6c81b987a82f5f399bd104fb0eeb9b2f7b Mon Sep 17 00:00:00 2001 From: Balazs Racz Date: Fri, 29 Dec 2023 10:20:24 +0100 Subject: [PATCH] Limits end to end buffering in gridconnect bridge. When a dispatcher was used to send traffic to a gridconnect bridge, an infinite number of packets were allocated in the dispatcher when more than one client was connected. By adding a limitedpool to the bridge object, we can ensure that the dispatcher is blocked when the output queue pushes back. --- src/utils/GridConnectHub.cxx | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/src/utils/GridConnectHub.cxx b/src/utils/GridConnectHub.cxx index b148d06ae..79408b756 100644 --- a/src/utils/GridConnectHub.cxx +++ b/src/utils/GridConnectHub.cxx @@ -135,6 +135,14 @@ class GCAdapter : public GCAdapterBase , skipMember_(skip_member) , double_bytes_(double_bytes) { + const int cnt = config_gridconnect_bridge_max_outgoing_packets(); + if (cnt > 1) { + ownedPool_.reset( + new LimitedPool(sizeof(Buffer), cnt)); + pool_ = ownedPool_.get(); + } else { + pool_ = mainBufferPool; + } } /// @return where to write the packets to. @@ -143,10 +151,27 @@ class GCAdapter : public GCAdapterBase return destination_; } - bool shutdown() { - return delayPort_.shutdown(); + /// @return Triggers releasing all memory after a close. Returns true + /// if it's safe to delete this. + bool shutdown() + { + const int cnt = config_gridconnect_bridge_max_outgoing_packets(); + bool state_delay = delayPort_.shutdown(); + bool state_pool = true; + if (ownedPool_) + { + state_pool = (int(ownedPool_->free_items()) == cnt); + } + return state_delay && state_pool; } - + + /// The dispatcher will be using this pool to allocate frames when a + /// hub needs to make a copy for an outgoing queue. + Pool *pool() override + { + return pool_; + } + Action entry() override { LOG(VERBOSE, "can packet arrived: %" PRIx32, @@ -185,6 +210,10 @@ class GCAdapter : public GCAdapterBase /// Helper class that assembles larger outgoing packets from the /// individual packets by delaying data a little bit. BufferPort delayPort_; + /// If we want frame limits, this pool can do that for us. + std::unique_ptr ownedPool_; + /// The allocation buffer pool to use for outgoing frames. + Pool* pool_; /// Destination buffer (characters). char dbuf_[56]; /// Pipe to send data to.