Skip to content

Commit

Permalink
Limits end to end buffering in gridconnect bridge.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
balazsracz committed Dec 29, 2023
1 parent 2a1f4b3 commit 4bd04c6
Showing 1 changed file with 32 additions and 3 deletions.
35 changes: 32 additions & 3 deletions src/utils/GridConnectHub.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -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<CanHubData>), cnt));
pool_ = ownedPool_.get();
} else {
pool_ = mainBufferPool;
}
}

/// @return where to write the packets to.
Expand All @@ -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,
Expand Down Expand Up @@ -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<LimitedPool> ownedPool_;
/// The allocation buffer pool to use for outgoing frames.
Pool* pool_;
/// Destination buffer (characters).
char dbuf_[56];
/// Pipe to send data to.
Expand Down

0 comments on commit 4bd04c6

Please sign in to comment.