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 : 84 : bool ShmConf::auto_init_roudi(bool same_process_from_roudi, int memory_strategy) { 55 : 84 : return ShmFactory::auto_init_roudi(same_process_from_roudi, memory_strategy); 56 : : } 57 : : 58 : 1 : void ShmConf::init_roudi(const std::string& config_path, int memory_strategy, bool monitoring_enable) { 59 : 1 : Bytes::init_memory_pool(); 60 : : 61 : 1 : ShmFactory::init_roudi(config_path, memory_strategy, monitoring_enable); 62 : 1 : } 63 : : 64 : 2 : void ShmConf::init_runtime(const std::string& name, bool same_process_from_roudi) { 65 [ + + ]: 2 : if VUNLIKELY (name.size() > kMaxStringSize) { 66 [ + - + - : 2 : VLOG_F("ShmConf: Input string length is too long."); - + ] 67 : : 68 : 0 : return; 69 : : } 70 : : 71 : 1 : Bytes::init_memory_pool(); 72 : : 73 [ + - ]: 1 : ShmFactory::init_runtime(name, same_process_from_roudi); 74 : : } 75 : : 76 : 0 : void ShmConf::deinit_runtime() { ShmFactory::deinit_runtime(); } 77 : : 78 : 1 : void ShmConf::global_init() { 79 : 1 : Bytes::init_memory_pool(); 80 : : 81 : 1 : ShmFactory::get(); 82 : 1 : } 83 : : 84 : 101 : bool ShmConf::parse_protocol(struct Protocol* protocol) { 85 [ - + ]: 101 : 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 [ + + ]: 101 : if VUNLIKELY (protocol->host.empty()) { 92 : 1 : return false; 93 : : } 94 : : 95 [ - + - - : 100 : address = protocol->host + (protocol->path.empty() ? "" : "/" + protocol->path); + - + - - + - - ] 96 [ + - + - : 100 : event = protocol->dictionary["event"]; + - ] 97 [ + - + - ]: 100 : domain = Helpers::to_int(protocol->dictionary["domain"], 0); 98 [ + - + - ]: 100 : depth = Helpers::to_int(protocol->dictionary["depth"], 0); 99 : : 100 [ + - + - ]: 100 : const auto& history_str = protocol->dictionary["history"]; 101 : : 102 [ + + ]: 100 : if (history_str.empty()) { 103 [ + + + + : 99 : if (get_impl_type() == kSetter || get_impl_type() == kGetter) { + + ] 104 : 19 : history = 1; 105 : : } else { 106 : 80 : history = 0; 107 : : } 108 : : } else { 109 : 1 : history = Helpers::to_int(history_str, 0); 110 : : } 111 : : 112 [ + - + - ]: 100 : wait = Helpers::to_int(protocol->dictionary["wait"], 0); 113 : : 114 [ + + + + : 103 : 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 : 96 : return true; 122 : : } 123 : : 124 : 24 : std::unique_ptr<ServerImpl> ShmConf::create_server() const { return std::make_unique<ShmServerImpl>(*this); } 125 : : 126 : 24 : std::unique_ptr<ClientImpl> ShmConf::create_client() const { return std::make_unique<ShmClientImpl>(*this); } 127 : : 128 : 53 : std::unique_ptr<PublisherImpl> ShmConf::create_publisher() const { return std::make_unique<ShmPublisherImpl>(*this); } 129 : : 130 : 65 : std::unique_ptr<SubscriberImpl> ShmConf::create_subscriber() const { 131 : 65 : return std::make_unique<ShmSubscriberImpl>(*this); 132 : : } 133 : : 134 : 14 : std::unique_ptr<SetterImpl> ShmConf::create_setter() const { return std::make_unique<ShmSetterImpl>(*this); } 135 : : 136 : 18 : std::unique_ptr<GetterImpl> ShmConf::create_getter() const { return std::make_unique<ShmGetterImpl>(*this); } 137 : : 138 : 204 : bool ShmConf::is_valid() const { 139 [ + + ]: 204 : if VUNLIKELY (address.empty()) { 140 : 1 : return false; 141 : : } 142 : : 143 [ + + + + : 203 : if VUNLIKELY (address.size() > kMaxStringSize || event.size() > kMaxStringSize) { + + ] 144 : 2 : return false; 145 : : } 146 : : 147 [ + + + + : 201 : if VUNLIKELY (domain < 0 || depth < 0 || history < 0) { + + + + + + ] 148 : 3 : return false; 149 : : } 150 : : 151 : 198 : return true; 152 : : } 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 : 2 : TransportType get_transport_type() const override { return TransportType::kShm; } 169 : : 170 : 2 : std::unique_ptr<Conf> create() const override { return std::make_unique<ShmConf>(); } 171 : : }; 172 : : 173 : : #ifdef VLINK_LIBRARY 174 [ + + + - : 4 : VLINK_PLUGIN_DECLARE(ConfPluginShm, 1, 0) + - + - - + ] 175 : : #endif 176 : : 177 : : } // namespace vlink