hmbdc
simplify-high-performance-messaging-programming
ContextDetail.hpp
1 #include "hmbdc/Copyright.hpp"
2 #pragma once
3 
4 #include "hmbdc/app/Client.hpp"
5 #include "hmbdc/app/Message.hpp"
6 
7 #include "hmbdc/pattern/PoolT.hpp"
8 #include "hmbdc/pattern/PoolMinus.hpp"
9 #include "hmbdc/pattern/LockFreeBufferT.hpp"
10 #include "hmbdc/pattern/MonoLockFreeBuffer.hpp"
11 
12 #include "hmbdc/os/Thread.hpp"
13 #include "hmbdc/os/Allocators.hpp"
14 #include "hmbdc/time/Timers.hpp"
15 
16 #include <vector>
17 #include <type_traits>
18 #include <thread>
19 #include <utility>
20 
21 namespace hmbdc { namespace app { namespace context_detail {
22 
23 template <typename CcClient>
26  template <typename U = CcClient>
27  PoolConsumerProxy(U& client
28  , size_t* pDispStartCount
29  , typename std::enable_if<std::is_base_of<time::TimerManager, U>::value>::type* = nullptr)
30  : pattern::PoolConsumer(CcClient::INTERESTS_SIZE != 0, &client, pDispStartCount)
31  , client_(client){}
32 
33  template <typename U = CcClient>
34  PoolConsumerProxy(U& client
35  , size_t* pDispStartCount
36  , typename std::enable_if<!std::is_base_of<time::TimerManager, U>::value>::type* = nullptr)
37  : pattern::PoolConsumer(CcClient::INTERESTS_SIZE != 0, nullptr, pDispStartCount)
38  , client_(client){}
39 
40  virtual size_t handleRangeImpl(BufIt it,
41  BufIt end, uint16_t threadSerialNumber) override {
42  return client_.CcClient::handleRangeImpl(it, end, threadSerialNumber);
43  }
44  virtual void messageDispatchingStartedCb(size_t const* dispStartCount) override {
45  client_.CcClient::messageDispatchingStartedCb(dispStartCount);
46  }
47  virtual void invokedCb(size_t n) override {
48  client_.CcClient::invokedCb(n);
49  }
50  virtual void stoppedCb(std::exception const&e) override {
51  client_.CcClient::stoppedCb(e);
52  }
53  virtual bool droppedCb() override {
54  if (client_.CcClient::droppedCb()) {
55  delete this;
56  return true;
57  } else {
58  return false;
59  }
60  }
61 private:
62  CcClient& HMBDC_RESTRICT client_;
63 };
64 
65 template <typename... ContextProperties>
69  enum {
70  broadcast_msg = 1,
71  has_pool = 1,
72  pool_msgless = 0,
73  ipc = 0,
74  dispatch_reverse = 0,
75  };
76 };
77 
78 template <uint16_t c, typename... ContextProperties>
79 struct context_property_aggregator<context_property::broadcast<c>
80  , ContextProperties...>
81 : context_property_aggregator<ContextProperties...> {
83  static_assert(context_property_aggregator<ContextProperties...>::broadcast_msg, "contradicting properties");
84  enum {
85  broadcast_msg = 1,
86  has_pool = 1,
87  };
88 };
89 
90 template <typename... ContextProperties>
91 struct context_property_aggregator<context_property::partition
92  , ContextProperties...>
93 : context_property_aggregator<ContextProperties...> {
95  enum {
96  broadcast_msg = 0,
97  has_pool = context_property_aggregator<ContextProperties...>::pool_msgless,
98  };
99 };
100 
101 template <typename... ContextProperties>
102 struct context_property_aggregator<context_property::msgless_pool
103  , ContextProperties...>
104 : context_property_aggregator<ContextProperties...> {
105  enum {
106  has_pool = 1,
107  pool_msgless = 1
108  };
109 };
110 
111 template <typename... ContextProperties>
112 struct context_property_aggregator<context_property::ipc_enabled
113  , ContextProperties...>
114 : context_property_aggregator<ContextProperties...> {
116  enum {
117  ipc = 1,
118  };
119 };
120 
121 template <typename... ContextProperties>
122 struct context_property_aggregator<context_property::pci_ipc
123  , ContextProperties...>
124 : context_property_aggregator<ContextProperties...> {
126  enum {
127  ipc = 1,
128  };
129 };
130 
131 template <bool is_timer_manager>
132 struct tm_runner {
133  template<typename C>
134  void operator()(C&) {}
135 };
136 
137 template <>
138 struct tm_runner<true> {
139  void operator()(hmbdc::time::TimerManager& tm) {
140  tm.checkTimers(hmbdc::time::SysTime::now());
141  }
142 };
143 
144 template <typename LFB, typename CcClient>
145 bool runOnceImpl(uint16_t hmbdcNumber, bool& HMBDC_RESTRICT stopped
146  , LFB& HMBDC_RESTRICT lfb, CcClient& HMBDC_RESTRICT c) {
147  typename LFB::iterator begin, end;
148  try {
150  tr(c);
151 
152  using Cc = typename std::decay<CcClient>::type;
153 
154  const bool clientParticipateInMessaging = Cc::INTERESTS_SIZE != 0;
155  if (clientParticipateInMessaging) {
156  uint64_t count = lfb.peek(hmbdcNumber, begin, end, c.maxBatchMessageCount());
157  c.Cc::invokedCb(c.Cc::handleRangeImpl(begin, end, hmbdcNumber));
158  lfb.wasteAfterPeek(hmbdcNumber, count);
159  } else {
160  c.Cc::invokedCb(0);
161  }
162  } catch (std::exception const& e) {
163  if (!stopped) {
164  c.stopped(e);
165  return !c.dropped();
166  }
167  } catch (int code) {
168  if (!stopped) {
169  c.stopped(hmbdc::ExitCode(code));
170  return !c.dropped();
171  }
172  } catch (...) {
173  if (!stopped) {
174  c.stopped(hmbdc::UnknownException());
175  return !c.dropped();
176  }
177  }
178  return !stopped;
179 }
180 
181 template <typename CcClient>
182 bool runOnceImpl(uint16_t threadSerialNumber, bool& HMBDC_RESTRICT stopped
183  , hmbdc::pattern::MonoLockFreeBuffer& HMBDC_RESTRICT lfb, CcClient& HMBDC_RESTRICT c) {
185  try {
186  tm_runner<std::is_base_of<hmbdc::time::TimerManager, CcClient>::value> tr;
187  tr(c);
188 
189  using Cc = typename std::decay<CcClient>::type;
190  const bool clientParticipateInMessaging = Cc::INTERESTS_SIZE != 0;
191  if (clientParticipateInMessaging) {
192  uint64_t count = lfb.peek(begin, end, c.maxBatchMessageCount());
193  c.Cc::invokedCb(c.Cc::handleRangeImpl(begin, end, threadSerialNumber));
194  lfb.wasteAfterPeek(begin, count);
195  } else {
196  c.Cc::invokedCb(0);
197  }
198  } catch (std::exception const& e) {
199  if (!stopped) {
200  c.stopped(e);
201  return !c.dropped();
202  }
203  } catch (int code) {
204  if (!stopped) {
205  c.stopped(hmbdc::ExitCode(code));
206  return !c.dropped();
207  }
208  } catch (...) {
209  if (!stopped) {
210  c.stopped(hmbdc::UnknownException());
211  return !c.dropped();
212  }
213  }
214  return !stopped;
215 }
216 
217 inline
218 void unblock(hmbdc::pattern::MonoLockFreeBuffer& buffer, uint16_t){
219  buffer.reset();
220 }
221 
222 template <typename Buffer>
223 void unblock(Buffer& lfb, uint16_t threadSerialNumber) {
224  lfb.markDead(threadSerialNumber);
225 }
226 
227 }}}
Definition: MonoLockFreeBuffer.hpp:16
Definition: ContextDetail.hpp:132
Definition: Timers.hpp:70
the default vanilla allocate
Definition: Allocators.hpp:157
Unknown excpetion.
Definition: Exception.hpp:17
similar to ShmBasePtrAllocator but using dev memory
Definition: Allocators.hpp:130
Definition: ContextDetail.hpp:24
Definition: LockFreeBufferT.hpp:18
Definition: PoolConsumer.hpp:16
Exception that just has an exit code.
Definition: Exception.hpp:28
helping allocating object and its aggregated objects in a continouse shared memory ...
Definition: Allocators.hpp:95
Definition: Base.hpp:12
Definition: LockFreeBufferMisc.hpp:89