EMANE  1.2.1
flowcontrolclient.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013-2014,2016 - Adjacent Link LLC, Bridgewater, New
3  * Jersey
4  * Copyright (c) 2010 - DRS CenGen, LLC, Columbia, Maryland
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in
15  * the documentation and/or other materials provided with the
16  * distribution.
17  * * Neither the name of DRS CenGen, LLC nor the names of its
18  * contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  */
34 
36 
37 #include <mutex>
38 #include <condition_variable>
39 
40 class EMANE::FlowControlClient::Implementation
41 {
42 public:
43  Implementation(EMANE::UpstreamTransport & transport):
44  rTransport_(transport),
45  bCancel_{false},
46  u16TokensAvailable_{}{}
47 
48  ~Implementation(){}
49 
50  void start()
51  {
52  std::lock_guard<std::mutex> m(mutex_);
53 
54  // send message
55  rTransport_.sendDownstreamControl({Controls::FlowControlControlMessage::create(u16TokensAvailable_)});
56  }
57 
58  void stop()
59  {
60  std::lock_guard<std::mutex> m(mutex_);
61 
62  // set cancel flag
63  bCancel_ = true;
64 
65  // unblock pending request if any
66  cond_.notify_one();
67  }
68 
69  std::pair<std::uint16_t,bool> removeToken()
70  {
71  std::unique_lock<std::mutex> lock{mutex_};
72 
73  // request status
74  bool bStatus{false};
75 
76  // wait unitil tokens are available, and not canceled
77  while(u16TokensAvailable_ == 0 && !bCancel_)
78  {
79  cond_.wait(lock);
80  }
81 
82  // check canceled flag
83  if(bCancel_)
84  {
85  // failure
86  bStatus = false;
87  }
88  else
89  {
90  // success
91  bStatus = true;
92 
93  // remove token
94  --u16TokensAvailable_;
95  }
96 
97  return {u16TokensAvailable_,bStatus};
98  }
99 
100  void processFlowControlMessage(const Controls::FlowControlControlMessage * pMessage)
101  {
102  std::lock_guard<std::mutex> m(mutex_);
103 
104  u16TokensAvailable_ = pMessage->getTokens();
105 
106  rTransport_.sendDownstreamControl({Controls::FlowControlControlMessage::create(u16TokensAvailable_)});
107 
108  // unblock pending request if any
109  cond_.notify_one();
110  }
111 
112 private:
113  EMANE::UpstreamTransport & rTransport_;
114 
115  bool bCancel_;
116 
117  std::mutex mutex_;
118 
119  std::condition_variable cond_;
120 
121  std::uint16_t u16TokensAvailable_;
122 };
123 
125  pImpl_{new Implementation{transport}}
126 {}
127 
128 
129 
131 {}
132 
133 
135 {
136  pImpl_->start();
137 }
138 
139 
141 {
142  pImpl_->stop();
143 }
144 
145 
146 
147 std::pair<std::uint16_t,bool> EMANE::FlowControlClient::removeToken()
148 {
149  return pImpl_->removeToken();
150 }
151 
152 
154 {
155  return pImpl_->processFlowControlMessage(pMessage);
156 }
void processFlowControlMessage(const Controls::FlowControlControlMessage *pMsg)
static FlowControlControlMessage * create(const Serialization &serialization)
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()
UpstreamTransport allows for processing upstream data and control messages. Upstream packets and cont...
FlowControlClient(EMANE::UpstreamTransport &transport)