hmbdc
simplify-high-performance-messaging-programming
Messages.hpp
1 #include "hmbdc/Copyright.hpp"
2 #pragma once
3 #include "hmbdc/app/Message.hpp"
4 
5 #include <memory>
6 #include <assert.h>
7 
8 namespace hmbdc { namespace tips {
9 /**
10  * @brief Each TIPS Message type could optionally specify if the message delivery
11  * should be dissabled for some types of delivery using these Masks
12  * See below:
13  * struct noLocal {
14  * static uint32_t tipsDisableSendMask() {
15  * return INTER_THREAD;
16  * }
17  * };
18  * struct MyMsgNotDeliverredWithinLocalProcess : app::hasTag<1001>, noLocal{};
19  */
20 enum DisableSendMask {
21  DEFAULT_DISABLED= 0,
22  INTER_THREAD = 1 << 0,
23  INTER_PROCESS = 1 << 1,
24  OVER_NETWORK = 1 << 2,
25 };
26 
27 HMBDC_CLASS_HAS_DECLARE(tipsDisableSendMask); /// internal use
28 HMBDC_CLASS_HAS_DECLARE(hmbdc0cpyShmRefCount); /// internal use
29 
30 /**
31  * @brief Message that need to be IPCed and/or go through Network
32  * can derived from this type if it holds 1 (and only 1)
33  * shared ptr to an already serilized POD type
34  *
35  * use this instead of app::hasMemoryAttachment directly to avoid the
36  * complication of releasing the attachment
37  *
38  * @tparam Mesasge the concrete Message type thatderived from this tmeplate
39  * @tparam T the underlying POD data type
40  */
41 template <MessageC Message, typename T>
43  using SP = std::shared_ptr<T>;
44  static_assert(std::is_trivially_copyable<T>::value);
45  SP attachmentSp; /// the attachment
46  size_t len = 0; /// the length of the POD data
47 
48  /**
49  * @brief empty ctor
50  *
51  */
53  {}
54 
55 
56  /**
57  * @brief Construct a new has Shared Ptr Attachment object
58  *
59  * @param attachmentIn input shared_ptr
60  * @param len byte size of the attachment
61  */
62  hasSharedPtrAttachment(SP attachmentIn, size_t len = sizeof(T))
63  : attachmentSp(attachmentIn)
64  , len(len) {
65  static_assert(sizeof(app::hasMemoryAttachment::clientData) == sizeof(std::shared_ptr<T>));
66  }
67 
68  /**
69  * @brief internal use
70  *
71  */
74  , Message::tagBase::type {
75  private:
76  using tagBase = typename Message::tagBase;
77  static constexpr size_t meatOffsetInMessage = sizeof(SP) + sizeof(size_t)
78  + tagBase::size;
79  char meat[sizeof(Message) - meatOffsetInMessage];
80 
81  public:
82  enum {
83  is_att_0cpyshm = has_hmbdc0cpyShmRefCount<T>::value,
84  };
85  uint64_t hmbdcShmRefCount = 0;
86  hmbdcSerialized(Message const& message)
87  : tagBase::type(message) {
88  afterConsumedCleanupFunc = [](app::hasMemoryAttachment* h) {
89  auto psp = (SP*)h->app::hasMemoryAttachment::clientData;
90  psp->SP::~SP();
91  h->app::hasMemoryAttachment::afterConsumedCleanupFunc = nullptr;
92  };
93  attachment = message.hasSharedPtrAttachment::attachmentSp.get();
94  len = message.hasSharedPtrAttachment::len;
95  new (this->clientData) SP(message.hasSharedPtrAttachment::attachmentSp);
96  memcpy(meat, (char*)&message + meatOffsetInMessage, sizeof(meat));
97  }
98 
99  Message toHmbdcUnserialized() {
100  auto& att = (app::hasMemoryAttachment&)(*this);
101  assert(att.attachment);
102  char resSpace[sizeof(Message)] = {0};
103  auto& res = *(Message*)resSpace;
104  if constexpr (Message::hasRange) {
105  res.resetTypeTagOffsetInRange(this->typeTagOffsetInRange);
106  }
107  memcpy((char*)&res + meatOffsetInMessage, meat, sizeof(meat));
108 
109  res.Message::hasSharedPtrAttachment::attachmentSp
110  = SP((typename SP::element_type*)(att.attachment)
111  , [hasMemoryAttachment = att](void*) mutable {
112  hasMemoryAttachment.release();
113  }
114  );
115  res.Message::hasSharedPtrAttachment::len = app::hasMemoryAttachment::len;
116  Message toReturn = res;
117  res.Message::~Message();
118  att.attachment = nullptr;
119  return toReturn;
120  };
121  };
122 
123  /**
124  * @brief internal use
125  */
126  auto toHmbdcSerialized() const {
127  return hmbdcSerialized{static_cast<Message const&>(*this)};
128  }
129 };
130 
131 /**
132  * @brief Any non-POD Message type M can be transferred over IPC or network
133  * if "S M::toHmbdcSerialized() const" is implemented and S is POD or
134  * an app::hasMemoryAttachment Mesage type;
135  * AND
136  * M "S::toHmbdcUnserialized()" is implemented.
137  */
138 HMBDC_CLASS_HAS_DECLARE(toHmbdcSerialized); /// internal use
139 HMBDC_CLASS_HAS_DECLARE(toHmbdcUnserialized); /// internal use
140 
141 
142 }}
internal use
Definition: Messages.hpp:72
hasMemoryAttachment()
default ctor
Definition: Message.hpp:130
auto toHmbdcSerialized() const
internal use
Definition: Messages.hpp:126
hasSharedPtrAttachment()
the length of the POD data
Definition: Messages.hpp:52
size_t len
the attachment
Definition: Messages.hpp:46
hasSharedPtrAttachment(SP attachmentIn, size_t len=sizeof(T))
Construct a new has Shared Ptr Attachment object.
Definition: Messages.hpp:62
if a specific hmbdc network transport (for example tcpcast, rmcast, and rnetmap) supports message wit...
Definition: Message.hpp:125
Definition: Base.hpp:12
uint64_t clientData[2]
byte size of the above
Definition: Message.hpp:183
internal use
Definition: Messages.hpp:42