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 "./modules/shm_conf.h" 25 : : 26 : : #include <memory> 27 : : #include <string> 28 : : #include <thread> 29 : : 30 : : #include "./base/helpers.h" 31 : : #include "./base/logger.h" 32 : : #include "./impl/conf_plugin_interface.h" 33 : : #include "./impl/url.h" 34 : : #include "./shm_client_impl.h" 35 : : #include "./shm_getter_impl.h" 36 : : #include "./shm_publisher_impl.h" 37 : : #include "./shm_server_impl.h" 38 : : #include "./shm_setter_impl.h" 39 : : #include "./shm_subscriber_impl.h" 40 : : 41 : : namespace vlink { 42 : : 43 : : VLINK_DEFINE_GLOBAL_PROPERTY(ShmConf) 44 : : 45 : : static constexpr size_t kMaxStringSize = 80U; 46 : : 47 : : // ShmConf 48 : 3 : bool ShmConf::has_roudi_inited() { return ShmFactory::has_roudi_inited(); } 49 : : 50 : 2 : bool ShmConf::has_runtime_inited() { return ShmFactory::has_runtime_inited(); } 51 : : 52 : 2 : bool ShmConf::has_roudi_running() { return ShmFactory::has_roudi_running(); } 53 : : 54 : 72 : bool ShmConf::auto_init_roudi(bool same_process_from_roudi) { 55 : 72 : return ShmFactory::auto_init_roudi(same_process_from_roudi); 56 : : } 57 : : 58 : 2 : void ShmConf::init_runtime(const std::string& name, bool same_process_from_roudi) { 59 [ + + ]: 2 : if VUNLIKELY (name.size() > kMaxStringSize) { 60 [ + - - + ]: 2 : VLOG_F("ShmConf: Input string length is too long."); 61 : : 62 : 0 : return; 63 : : } 64 : : 65 : 1 : Bytes::init_memory_pool(); 66 : : 67 [ + - ]: 1 : ShmFactory::init_runtime(name, same_process_from_roudi); 68 : : } 69 : : 70 : 0 : void ShmConf::deinit_runtime() { ShmFactory::deinit_runtime(); } 71 : : 72 : 1 : void ShmConf::init_roudi(const std::string& config_path, int memory_strategy, bool monitoring_enable) { 73 : 1 : Bytes::init_memory_pool(); 74 : : 75 : 1 : ShmFactory::init_roudi(config_path, memory_strategy, monitoring_enable); 76 : 1 : } 77 : : 78 : 1 : void ShmConf::global_init() { 79 : 1 : Bytes::init_memory_pool(); 80 : : 81 : 1 : ShmFactory::get(); 82 : 1 : } 83 : : 84 : 99 : bool ShmConf::parse_protocol(struct Protocol* protocol) { 85 [ - + ]: 99 : if VUNLIKELY (get_impl_type() == kUnknownImplType) { 86 [ # # # # ]: 0 : VLOG_F("ShmConf: Unknown node type, cannot parse protocol."); 87 : : 88 : 0 : return false; 89 : : } 90 : : 91 [ + + ]: 99 : if VUNLIKELY (protocol->host.empty()) { 92 : 1 : return false; 93 : : } 94 : : 95 [ - + - - : 98 : address = protocol->host + (protocol->path.empty() ? "" : "/" + protocol->path); + - + - - + - - ] 96 [ + - + - : 98 : event = protocol->dictionary["event"]; + - ] 97 [ + - + - ]: 98 : domain = Helpers::to_int(protocol->dictionary["domain"], 0); 98 [ + - + - ]: 98 : depth = Helpers::to_int(protocol->dictionary["depth"], 0); 99 : : 100 [ + - + - ]: 98 : const auto& history_str = protocol->dictionary["history"]; 101 : : 102 [ + + ]: 98 : if (history_str.empty()) { 103 [ + + + + : 97 : if (get_impl_type() == kSetter || get_impl_type() == kGetter) { + + ] 104 : 18 : history = 1; 105 : : } else { 106 : 79 : history = 0; 107 : : } 108 : : } else { 109 : 1 : history = Helpers::to_int(history_str, 0); 110 : : } 111 : : 112 [ + - + - ]: 98 : wait = Helpers::to_int(protocol->dictionary["wait"], 0); 113 : : 114 [ + + + + : 101 : if (wait > 0 && (get_impl_type() == kClient || get_impl_type() == kServer || get_impl_type() == kSetter || + + + + + + ] 115 [ + + ]: 3 : get_impl_type() == kGetter)) { 116 [ + - + - ]: 8 : VLOG_W("ShmConf: Wait mode must be Event(Pub/Sub)."); 117 : : 118 : 4 : return false; 119 : : } 120 : : 121 : 94 : return true; 122 : : } 123 : : 124 : 167 : bool ShmConf::is_valid() const { 125 [ + + ]: 167 : if VUNLIKELY (address.empty()) { 126 : 1 : return false; 127 : : } 128 : : 129 [ + + + + : 166 : if VUNLIKELY (address.size() > kMaxStringSize || event.size() > kMaxStringSize) { + + ] 130 : 2 : return false; 131 : : } 132 : : 133 [ + + + + : 164 : if VUNLIKELY (domain < 0 || depth < 0 || history < 0) { + + + + + + ] 134 : 3 : return false; 135 : : } 136 : : 137 : 161 : return true; 138 : : } 139 : : 140 : 20 : std::unique_ptr<ServerImpl> ShmConf::create_server() const { return std::make_unique<ShmServerImpl>(*this); } 141 : : 142 : 17 : std::unique_ptr<ClientImpl> ShmConf::create_client() const { return std::make_unique<ShmClientImpl>(*this); } 143 : : 144 : 43 : std::unique_ptr<PublisherImpl> ShmConf::create_publisher() const { return std::make_unique<ShmPublisherImpl>(*this); } 145 : : 146 : 55 : std::unique_ptr<SubscriberImpl> ShmConf::create_subscriber() const { 147 : 55 : return std::make_unique<ShmSubscriberImpl>(*this); 148 : : } 149 : : 150 : 12 : std::unique_ptr<SetterImpl> ShmConf::create_setter() const { return std::make_unique<ShmSetterImpl>(*this); } 151 : : 152 : 14 : std::unique_ptr<GetterImpl> ShmConf::create_getter() const { return std::make_unique<ShmGetterImpl>(*this); } 153 : : 154 : 1 : std::ostream& operator<<(std::ostream& ostream, const ShmConf& conf) noexcept { 155 : 1 : std::ios_base::fmtflags f = ostream.flags(); 156 : : 157 : : ostream << "ShmConf:" 158 : 1 : << "[type]" << +conf.get_impl_type() << "[address]" << conf.address << "[event]" << conf.event << "[domain]" 159 : 1 : << conf.domain << "[depth]" << conf.depth << "[history]" << conf.history << "[wait]" << conf.wait; 160 : : 161 : 1 : ostream.flags(f); 162 : : 163 : 1 : return ostream; 164 : : } 165 : : 166 : : class ConfPluginShm : public ConfPluginInterface { 167 : : protected: 168 : 0 : TransportType get_transport_type() const override { return TransportType::kShm; } 169 : : 170 : 0 : std::unique_ptr<Conf> create() const override { return std::make_unique<ShmConf>(); } 171 : : }; 172 : : 173 : : #ifdef VLINK_LIBRARY 174 [ # # # # : 0 : VLINK_PLUGIN_DECLARE(ConfPluginShm, 1, 0) # # # # # # ] 175 : : #endif 176 : : 177 : : } // namespace vlink