17#ifndef CYBER_TRANSPORT_TRANSMITTER_SHM_TRANSMITTER_H_
18#define CYBER_TRANSPORT_TRANSMITTER_SHM_TRANSMITTER_H_
66 std::atomic<int> serialized_receiver_count_;
67 std::atomic<int> arena_receiver_count_;
74 auto msg_o = msg.get();
75 auto arena_manager = ProtobufArenaManager::Instance();
76 if (!arena_manager->Enable() ||
77 !arena_manager->EnableSegment(this->attr_.channel_id())) {
78 ADEBUG <<
"arena manager enable failed.";
81 arena_manager->AcquireArenaMessage(channel_id_, msg);
82 if (msg.get() != msg_o) {
95 channel_id_(attr.channel_id()),
97 serialized_receiver_count_(0),
98 arena_receiver_count_(0) {
100 arena_transmit_ = common::GlobalData::Instance()->IsChannelEnableArenaShm(
111 if (arena_transmit_) {
113 message::MessageType<message::RawMessage>() ||
115 message::MessageType<message::PyMessageWrap>()) {
116 serialized_receiver_count_.fetch_add(1);
118 arena_receiver_count_.fetch_add(1);
121 serialized_receiver_count_.fetch_add(1);
123 if (!this->enabled_) {
130 if (this->enabled_) {
131 if (arena_transmit_) {
133 message::MessageType<message::RawMessage>() ||
135 message::MessageType<message::PyMessageWrap>()) {
136 serialized_receiver_count_.fetch_sub(1);
138 arena_receiver_count_.fetch_sub(1);
140 if (serialized_receiver_count_.load() <= 0 &&
141 arena_receiver_count_.load() <= 0) {
145 serialized_receiver_count_.fetch_sub(1);
146 if (serialized_receiver_count_.load() <= 0) {
155 if (this->enabled_) {
159 if (serialized_receiver_count_.load() == 0 &&
160 arena_receiver_count_.load() == 0) {
161 AERROR <<
"please enable shm transmitter by passing role attr.";
165 if (arena_transmit_) {
166 auto arena_manager = ProtobufArenaManager::Instance();
167 if (!arena_manager->Enable() ||
168 !arena_manager->EnableSegment(this->attr_.channel_id())) {
169 AERROR <<
"arena manager enable failed.";
176 this->enabled_ =
true;
181 if (this->enabled_) {
184 this->enabled_ =
false;
191 return Transmit(*msg, msg_info);
196 if (!this->enabled_) {
201 ReadableInfo readable_info;
202 WritableBlock arena_wb;
205 readable_info.set_host_id(host_id_);
206 readable_info.set_channel_id(channel_id_);
207 readable_info.set_arena_block_index(-1);
208 readable_info.set_block_index(-1);
210 if (arena_transmit_) {
212 std::size_t msg_size = 1024;
213 if (!segment_->AcquireArenaBlockToWrite(msg_size, &arena_wb)) {
214 AERROR <<
"acquire block failed.";
218 ADEBUG <<
"arena block index: " << arena_wb.index;
219 auto arena_manager = ProtobufArenaManager::Instance();
220 auto msg_wrapper = arena_manager->CreateMessageWrapper();
221 arena_manager->SetMessageChannelId(msg_wrapper.get(), channel_id_);
226 AERROR <<
"serialize to arena message wrapper failed.";
227 segment_->ReleaseArenaWrittenBlock(arena_wb);
230 auto segment = arena_manager->GetSegment(channel_id_);
245 memcpy(arena_wb.buf, msg_wrapper->GetData(), msg_size);
246 arena_wb.block->set_msg_size(msg_size);
248 char* msg_info_addr =
reinterpret_cast<char*
>(arena_wb.buf) + msg_size;
250 AERROR <<
"serialize message info failed.";
251 segment_->ReleaseArenaWrittenBlock(arena_wb);
255 readable_info.set_arena_block_index(arena_wb.index);
256 if (serialized_receiver_count_.load() > 0) {
258 if (!segment_->AcquireBlockToWrite(msg_size, &wb)) {
259 AERROR <<
"acquire block failed.";
263 ADEBUG <<
"block index: " << wb.index;
265 AERROR <<
"serialize to array failed.";
266 segment_->ReleaseWrittenBlock(wb);
269 wb.block->set_msg_size(msg_size);
271 char* msg_info_addr =
reinterpret_cast<char*
>(wb.buf) + msg_size;
273 AERROR <<
"serialize message info failed.";
274 segment_->ReleaseWrittenBlock(wb);
278 segment_->ReleaseWrittenBlock(wb);
279 segment_->ReleaseArenaWrittenBlock(arena_wb);
280 readable_info.set_block_index(wb.index);
282 segment_->ReleaseArenaWrittenBlock(arena_wb);
286 if (!segment_->AcquireBlockToWrite(msg_size, &wb)) {
287 AERROR <<
"acquire block failed.";
291 ADEBUG <<
"block index: " << wb.index;
293 AERROR <<
"serialize to array failed.";
294 segment_->ReleaseWrittenBlock(wb);
297 wb.block->set_msg_size(msg_size);
299 char* msg_info_addr =
reinterpret_cast<char*
>(wb.buf) + msg_size;
301 AERROR <<
"serialize message info failed.";
302 segment_->ReleaseWrittenBlock(wb);
306 segment_->ReleaseWrittenBlock(wb);
307 readable_info.set_block_index(wb.index);
310 ADEBUG <<
"Writing sharedmem message: "
312 <<
" to normal block: " << readable_info.block_index()
313 <<
" to arena block: " << readable_info.arena_block_index();
314 return notifier_->Notify(readable_info);
static std::string GetChannelById(uint64_t id)
static const std::size_t kSize
bool SerializeTo(std::string *dst) const
static NotifierPtr CreateNotifier()
static SegmentPtr CreateSegment(uint64_t channel_id)
std::shared_ptr< M > MessagePtr
ShmTransmitter(const RoleAttributes &attr)
virtual ~ShmTransmitter()
bool Transmit(const MessagePtr &msg, const MessageInfo &msg_info) override
bool AcquireMessage(std::shared_ptr< M > &msg)
std::size_t Hash(const std::string &key)
std::enable_if< HasSerializeToArray< T >::value, bool >::type SerializeToArray(const T &message, void *data, int size)
std::enable_if< HasByteSize< T >::value, int >::type ByteSize(const T &message)
std::enable_if< HasSerializeToArenaMessageWrapper< T >::value, bool >::type SerializeToArenaMessageWrapper(const T &message, ArenaMessageWrapper *wrapper, T **message_ptr)
std::shared_ptr< Segment > SegmentPtr
optional string message_type
optional uint64 channel_id