Branch data Line data Source code
1 : : /* 2 : : * Copyright (C) 2026 by Thun Lu. All rights reserved. 3 : : * Author: Thun Lu <thun.lu@zohomail.cn> 4 : : * Repo: https://github.com/thun-res/vlink 5 : : * _ __ __ _ __ 6 : : * | | / / / / (_) ____ / /__ 7 : : * | | / / / / / / / __ \ / //_/ 8 : : * | |/ / / /___ / / / / / / / ,< 9 : : * |___/ /_____/ /_/ /_/ /_/ /_/|_| 10 : : * 11 : : * Licensed under the Apache License, Version 2.0 (the "License"); 12 : : * you may not use this file except in compliance with the License. 13 : : * You may obtain a copy of the License at 14 : : * 15 : : * http://www.apache.org/licenses/LICENSE-2.0 16 : : * 17 : : * Unless required by applicable law or agreed to in writing, software 18 : : * distributed under the License is distributed on an "AS IS" BASIS, 19 : : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 : : * See the License for the specific language governing permissions and 21 : : * limitations under the License. 22 : : */ 23 : : 24 : : #include "./ddsc_getter_impl.hpp" 25 : : 26 : : #include <memory> 27 : : #include <utility> 28 : : 29 : : #include "./base/elapsed_timer.h" 30 : : #include "./base/message_loop.h" 31 : : 32 : : namespace vlink { 33 : : 34 : : // ReaderListener 35 : 22 : DdscGetterImpl::ReaderListener::ReaderListener(NodeImpl* impl) : DdscReaderListener(impl) {} 36 : : 37 : 25 : void DdscGetterImpl::ReaderListener::on_data_available(NodeImpl* impl, dds_entity_t reader) { 38 : 25 : auto* instance = static_cast<DdscGetterImpl*>(impl); 39 : 25 : auto* message_loop = instance->get_message_loop(); 40 : : 41 [ + + ]: 25 : if VUNLIKELY (instance->has_suspend.load(std::memory_order_acquire)) { 42 : 1 : DdscFactory::ReadMessage msg; 43 : : 44 [ + - + + ]: 2 : while (DdscFactory::take_data(reader, msg)) { 45 [ + - ]: 1 : DdscFactory::release_data(reader, msg); 46 : : 47 [ - + ]: 1 : if VUNLIKELY (instance->quit_flag_.load(std::memory_order_acquire)) { 48 : 0 : break; 49 : : } 50 : : } 51 : : 52 : 1 : return; 53 : 1 : } 54 : : 55 [ - + ]: 24 : if VUNLIKELY (!instance->callback_) { 56 : 0 : return; 57 : : } 58 : : 59 [ + + ]: 24 : if (message_loop) { 60 [ + - + - ]: 1 : message_loop->post_task([instance, reader]() { 61 [ - + ]: 1 : if VUNLIKELY (!instance->get_message_loop()) { 62 : 0 : return; 63 : : } 64 : : 65 : 1 : instance->process_message(reader); 66 : : }); 67 : : } else { 68 : 23 : instance->process_message(reader); 69 : : } 70 : : } 71 : : 72 : : // DdscGetterImpl 73 [ + - + - ]: 25 : DdscGetterImpl::DdscGetterImpl(const DdscConf& conf) : conf_(conf) {} 74 : : 75 : 24 : void DdscGetterImpl::process_message(dds_entity_t reader) { 76 : 24 : DdscFactory::ReadMessage msg; 77 : : 78 [ + - + + ]: 48 : while (DdscFactory::take_data(reader, msg)) { 79 [ - + ]: 24 : if VUNLIKELY (quit_flag_.load(std::memory_order_acquire)) { 80 [ # # ]: 0 : DdscFactory::release_data(reader, msg); 81 : 0 : break; 82 : : } 83 : : 84 [ - + ]: 24 : if VUNLIKELY (!msg.info.valid_data) { 85 [ # # ]: 0 : DdscFactory::release_data(reader, msg); 86 : 0 : continue; 87 : : } 88 : : 89 [ + + ]: 24 : if VUNLIKELY (is_latency_and_lost_enabled_.load(std::memory_order_acquire)) { 90 : 10 : last_latency_.store(ElapsedTimer::get_sys_timestamp(ElapsedTimer::kNano, false) - msg.timestamp, 91 : : std::memory_order_relaxed); 92 : : 93 : 10 : calc_sample_.update(msg.id, msg.guid); 94 : : } 95 : : 96 [ + - ]: 24 : callback_(msg.bytes); 97 : : 98 [ + - ]: 24 : DdscFactory::release_data(reader, msg); 99 : : } 100 : 24 : } 101 : : 102 : 22 : void DdscGetterImpl::init() { 103 [ + - ]: 22 : participant_ = DdscFactory::create_participant(kPublisher | kSubscriber, conf_, get_all_properties()); 104 : : 105 [ + - + - ]: 22 : topic_ = DdscFactory::create_topic(kPublisher | kSubscriber, conf_, participant_.get()); 106 : : 107 : 22 : subscriber_ = DdscFactory::create_subscriber(kSubscriber, conf_, participant_.get()); 108 : : 109 [ + - - + : 22 : if VUNLIKELY (!participant_ || !topic_) { - + ] 110 [ # # # # ]: 0 : VLOG_E("DdscGetterImpl::init(): participant/topic creation failed; getter left uninitialised."); 111 : : 112 : 0 : return; 113 : : } 114 : : 115 : 22 : quit_flag_.store(false, std::memory_order_release); 116 : : } 117 : : 118 : 22 : void DdscGetterImpl::deinit() { 119 : 22 : quit_flag_.store(true, std::memory_order_release); 120 : : 121 : 22 : detach(); 122 : : 123 : 22 : reader_.reset(); 124 : 22 : listener_.reset(); 125 : 22 : subscriber_.reset(); 126 : 22 : topic_.reset(); 127 : 22 : participant_.reset(); 128 : 22 : callback_ = {}; 129 : 22 : } 130 : : 131 : 2 : bool DdscGetterImpl::suspend() { 132 : 2 : has_suspend.store(true, std::memory_order_release); 133 : : 134 : 2 : return true; 135 : : } 136 : : 137 : 2 : bool DdscGetterImpl::resume() { 138 : 2 : has_suspend.store(false, std::memory_order_release); 139 : : 140 : 2 : return true; 141 : : } 142 : : 143 : 3 : bool DdscGetterImpl::is_suspend() const { return has_suspend.load(std::memory_order_acquire); } 144 : : 145 : 0 : const Conf* DdscGetterImpl::get_conf() const { return &conf_; } 146 : : 147 : 2 : const AbstractNode* DdscGetterImpl::get_abstract_node() const { return this; } 148 : : 149 : 4 : Status::BasePtr DdscGetterImpl::get_status(Status::Type type) const { 150 [ + + ]: 4 : if VUNLIKELY (!reader_) { 151 : 1 : return std::make_shared<Status::Unknown>(); 152 : : } 153 : : 154 : 3 : return ReaderListener::get_status(reader_->entity, type); 155 : : } 156 : : 157 : 1 : std::any DdscGetterImpl::get_native_handle() const { return subscriber_; } 158 : : 159 : 22 : bool DdscGetterImpl::listen(MsgCallback&& callback) { 160 [ - + ]: 22 : if VUNLIKELY (callback_) { 161 : 0 : return false; 162 : : } 163 : : 164 : 22 : callback_ = std::move(callback); 165 : : 166 [ + - ]: 22 : listener_.emplace(this); 167 : : 168 : 22 : reader_ = DdscFactory::create_datareader(kGetter, conf_, subscriber_.get(), topic_.get(), listener_->get_ptr()); 169 : : 170 : 22 : return true; 171 : : } 172 : : 173 : 4 : void DdscGetterImpl::set_latency_and_lost_enabled(bool enable) { 174 : 4 : is_latency_and_lost_enabled_.store(enable, std::memory_order_release); 175 : 4 : } 176 : : 177 : 4 : bool DdscGetterImpl::is_latency_and_lost_enabled() const { 178 : 4 : return is_latency_and_lost_enabled_.load(std::memory_order_acquire); 179 : : } 180 : : 181 : 2 : int64_t DdscGetterImpl::get_latency() const { 182 [ + + ]: 2 : if (!is_latency_and_lost_enabled_.load(std::memory_order_acquire)) { 183 : 1 : return 0; 184 : : } 185 : : 186 : 2 : return last_latency_.load(std::memory_order_relaxed); 187 : : } 188 : : 189 : 3 : SampleLostInfo DdscGetterImpl::get_lost() const { 190 [ + + ]: 3 : if (!is_latency_and_lost_enabled_.load(std::memory_order_acquire)) { 191 : 1 : return SampleLostInfo(); 192 : : } 193 : : 194 : 2 : return SampleLostInfo{calc_sample_.get_total(), calc_sample_.get_lost()}; 195 : : } 196 : : 197 : : } // namespace vlink