39 class EMANE::FlowControlManager::Implementation
43 rTransport_(transport),
44 u16TokensAvailable_{},
45 u16TotalTokensAvailable_{},
46 u16ShadowTokenCount_{},
47 u16LastTokensUpdate_{},
52 void start(std::uint16_t u16TotalTokensAvailable)
54 std::lock_guard<std::mutex> m(mutex_);
56 u16TotalTokensAvailable_ = u16TotalTokensAvailable;
57 u16TokensAvailable_ = u16TotalTokensAvailable;
59 sendFlowControlResponseMessage();
64 std::lock_guard<std::mutex> m(mutex_);
66 u16TotalTokensAvailable_ = 0;
67 u16TokensAvailable_ = 0;
68 u16ShadowTokenCount_ = 0;
71 std::pair<std::uint16_t,bool>
addToken(std::uint16_t u16Tokens)
73 std::lock_guard<std::mutex> m(mutex_);
76 const bool bStatus = ((u16TokensAvailable_ + u16Tokens) <= u16TotalTokensAvailable_);
82 u16TokensAvailable_ += u16Tokens;
86 if((u16ShadowTokenCount_ == 0) && (u16TokensAvailable_ > 0))
88 sendFlowControlResponseMessage();
91 return {u16TokensAvailable_,bStatus};
96 std::lock_guard<std::mutex> m(mutex_);
101 if(bAckPending_ ==
true)
108 if(u16TokensAvailable_ == 0)
115 --u16TokensAvailable_;
116 --u16ShadowTokenCount_;
122 return {u16TokensAvailable_,bStatus};
127 std::lock_guard<std::mutex> m(mutex_);
133 sendFlowControlResponseMessage();
139 if(pMsg->getTokens() == u16LastTokensUpdate_)
141 bAckPending_ =
false;
148 sendFlowControlResponseMessage();
155 DownstreamTransport & rTransport_;
159 std::uint16_t u16TokensAvailable_;
161 std::uint16_t u16TotalTokensAvailable_;
163 std::uint16_t u16ShadowTokenCount_;
165 std::uint16_t u16LastTokensUpdate_;
170 void sendFlowControlResponseMessage()
174 u16ShadowTokenCount_ = u16TokensAvailable_;
176 u16LastTokensUpdate_ = u16TokensAvailable_;
184 pImpl_{
new Implementation{transport}}
191 pImpl_->start(u16TotalTokensAvailable);
201 return pImpl_->addToken(u16Tokens);
206 return pImpl_->removeToken();
211 pImpl_->processFlowControlMessage(pMsg);
std::pair< std::uint16_t, bool > addToken(std::uint16_t u16Tokens=1)
FlowControlManager(EMANE::DownstreamTransport &transport)
void start(std::uint16_t u16TotalTokensAvailable)
static FlowControlControlMessage * create(const Serialization &serialization)
void processFlowControlMessage(const Controls::FlowControlControlMessage *pMsg)
Flow Control Control Messages are sent between a MAC layer and a transport in order to communicate da...
std::pair< std::uint16_t, bool > removeToken()
DownstreamTransport allows for processing downstream data and control messages.