LCOV - code coverage report
Current view: top level - src/impl - node_impl.cc (source / functions) Hit Total Coverage
Test: vlink Lines: 191 226 84.5 %
Date: 2026-09-30 18:30:16 Functions: 50 55 90.9 %
Branches: 181 350 51.7 %

           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 "./impl/node_impl.h"
      25                 :            : 
      26                 :            : #include <atomic>
      27                 :            : #include <charconv>
      28                 :            : #include <memory>
      29                 :            : #include <mutex>
      30                 :            : #include <shared_mutex>
      31                 :            : #include <utility>
      32                 :            : 
      33                 :            : #include "./base/bytes.h"
      34                 :            : #include "./base/logger.h"
      35                 :            : #include "./base/message_loop.h"
      36                 :            : #include "./extension/bag_writer.h"
      37                 :            : #include "./extension/discovery_reporter.h"
      38                 :            : #include "./impl/client_impl.h"
      39                 :            : #include "./impl/server_impl.h"
      40                 :            : #include "./private/license_check.h"
      41                 :            : #include "./version.h"
      42                 :            : 
      43                 :            : #ifdef VLINK_ENABLE_SECURITY
      44                 :            : #include <openssl/crypto.h>
      45                 :            : #endif
      46                 :            : 
      47                 :            : namespace vlink {
      48                 :            : 
      49                 :            : static constexpr bool kIgnoreIntraUrl{false};
      50                 :            : 
      51                 :            : // GlobalDiscoveryReporter
      52                 :            : struct GlobalDiscoveryReporter final {
      53                 :            :  public:
      54                 :       2418 :   static DiscoveryReporter* get(bool create_if_missing = true) {
      55   [ +  +  +  - ]:       2418 :     static GlobalDiscoveryReporter global;
      56                 :       2418 :     return global.get_instance(create_if_missing);
      57                 :            :   }
      58                 :            : 
      59                 :            :  private:
      60                 :            :   GlobalDiscoveryReporter() = default;
      61                 :            : 
      62                 :       2417 :   DiscoveryReporter* get_instance(bool create_if_missing) {
      63         [ +  - ]:       2417 :     std::lock_guard lock(mtx_);
      64                 :            : 
      65         [ +  - ]:       2418 :     check_disable_env();
      66                 :            : 
      67   [ +  +  +  -  :       2418 :     if (!create_if_missing || disabled_ || instance_) {
             +  +  +  + ]
      68                 :       2379 :       return instance_.get();
      69                 :            :     }
      70                 :            : 
      71         [ +  - ]:         39 :     instance_ = std::make_unique<DiscoveryReporter>();
      72         [ +  - ]:         39 :     instance_->async_run();
      73                 :            : 
      74                 :         39 :     return instance_.get();
      75                 :       2418 :   }
      76                 :            : 
      77                 :       2418 :   void check_disable_env() {
      78         [ +  + ]:       2418 :     if (disable_checked_) {
      79                 :       2364 :       return;
      80                 :            :     }
      81                 :            : 
      82                 :         54 :     disable_checked_ = true;
      83                 :            : 
      84   [ +  -  +  -  :         54 :     static std::string discovery = Utils::get_env("VLINK_DISCOVER_DISABLE");
          +  -  +  -  -  
                      - ]
      85                 :            : 
      86         [ -  + ]:         54 :     if (!discovery.empty()) {
      87                 :          0 :       int value = 0;
      88         [ #  # ]:          0 :       auto [p, error] = std::from_chars(discovery.data(), discovery.data() + discovery.size(), value);
      89                 :            : 
      90   [ #  #  #  # ]:          0 :       if (error == std::errc() && value == 1) {
      91   [ #  #  #  #  :          0 :         VLOG_I("DiscoveryReporter: Global discovery reporter is disabled.");
                   #  # ]
      92                 :          0 :         disabled_ = true;
      93                 :          0 :         return;
      94                 :            :       }
      95                 :            :     }
      96                 :            :   }
      97                 :            : 
      98                 :         54 :   ~GlobalDiscoveryReporter() = default;
      99                 :            : 
     100                 :            :   std::mutex mtx_;
     101                 :            :   bool disable_checked_{false};
     102                 :            :   bool disabled_{false};
     103                 :            :   std::unique_ptr<DiscoveryReporter> instance_;
     104                 :            : 
     105                 :            :   VLINK_DISALLOW_COPY_AND_ASSIGN(GlobalDiscoveryReporter)
     106                 :            : };
     107                 :            : 
     108                 :       2320 : static bool should_report_discovery(const NodeImpl& node) {
     109   [ +  +  +  +  :       2320 :   return node.is_discovery_enabled && !node.url.empty() && !node.is_security_type &&
                   +  + ]
     110                 :       2320 :          (!kIgnoreIntraUrl || node.transport_type != TransportType::kIntra);
     111                 :            : }
     112                 :            : 
     113                 :            : // AbstractNode
     114         [ +  - ]:          1 : std::any AbstractNode::get_native_handle() const { return nullptr; }
     115                 :            : 
     116                 :        960 : AbstractNode::AbstractNode() = default;
     117                 :            : 
     118                 :        960 : AbstractNode::~AbstractNode() = default;
     119                 :            : 
     120                 :            : // NodeImpl
     121                 :            : struct NodeImplHelper final {
     122                 :            :   std::atomic_bool is_interrupted{false};
     123                 :            : 
     124                 :            :   Conf::PropertiesMap property_map;
     125                 :            :   std::shared_mutex mtx;
     126                 :            :   std::shared_mutex status_mtx;
     127                 :            :   std::mutex post_mtx;
     128                 :            :   NodeImpl::StatusCallback status_callback;
     129                 :            :   std::atomic<MessageLoop*> message_loop{nullptr};
     130                 :            : 
     131                 :            :   std::shared_ptr<BagWriter> data_recorder;
     132                 :            :   std::atomic_bool data_recorder_enabled{false};
     133                 :            : };
     134                 :            : 
     135                 :          1 : bool NodeImpl::suspend() {
     136                 :            :   // has_suspend = true;
     137                 :            : 
     138   [ +  -  +  -  :          2 :   VLOG_W("Function [suspend] is not supported.");
                   +  - ]
     139                 :            : 
     140                 :          1 :   return false;
     141                 :            : }
     142                 :            : 
     143                 :          1 : bool NodeImpl::resume() {
     144                 :            :   // has_suspend = false;
     145                 :            : 
     146   [ +  -  +  -  :          2 :   VLOG_W("Function [resume] is not supported.");
                   +  - ]
     147                 :            : 
     148                 :          1 :   return false;
     149                 :            : }
     150                 :            : 
     151                 :          1 : bool NodeImpl::is_suspend() const {
     152   [ +  -  +  -  :          2 :   VLOG_W("Function [is_suspend] is not supported.");
                   +  - ]
     153                 :            : 
     154                 :          1 :   return false;
     155                 :            : }
     156                 :            : 
     157                 :       1166 : void NodeImpl::interrupt() { helper_->is_interrupted.store(true, std::memory_order_release); }
     158                 :            : 
     159                 :        955 : bool NodeImpl::is_support_loan() const { return false; }
     160                 :            : 
     161                 :          2 : Bytes NodeImpl::loan(int64_t size) {
     162                 :            :   (void)size;
     163                 :            : 
     164                 :          2 :   return Bytes();
     165                 :            : }
     166                 :            : 
     167                 :          7 : bool NodeImpl::return_loan(const Bytes& bytes) {
     168                 :            :   (void)bytes;
     169                 :            : 
     170                 :          7 :   return false;
     171                 :            : }
     172                 :            : 
     173                 :          2 : const struct Conf* NodeImpl::get_conf() const { return nullptr; }
     174                 :            : 
     175                 :          1 : const AbstractNode* NodeImpl::get_abstract_node() const { return nullptr; }
     176                 :            : 
     177                 :          1 : Status::BasePtr NodeImpl::get_status(Status::Type type) const {
     178                 :            :   (void)type;
     179                 :            : 
     180   [ +  -  +  -  :          2 :   VLOG_W("Function [get_status] is not supported.");
                   +  - ]
     181                 :            : 
     182                 :          1 :   return std::make_shared<Status::Unknown>();
     183                 :            : }
     184                 :            : 
     185                 :       1152 : bool NodeImpl::check_version(const Version& version) {
     186                 :       1152 :   Version runtime_version{VLINK_VERSION_MAJOR, VLINK_VERSION_MINOR, VLINK_VERSION_PATCH};
     187                 :            : 
     188         [ +  + ]:       1152 :   if VUNLIKELY (version != runtime_version) {
     189                 :            :     static std::atomic_bool print_warn{false};
     190                 :            : 
     191         [ +  + ]:          2 :     if VUNLIKELY (!print_warn.exchange(true, std::memory_order_relaxed)) {
     192   [ +  -  +  -  :          2 :       VLOG_W("The version may be incompatible. [Compiled]: ", version.to_string(),
          +  -  +  -  +  
             -  -  -  -  
                      - ]
     193                 :            :              " [Runtime]: ", runtime_version.to_string(), ".");
     194                 :            :     }
     195                 :            : 
     196                 :          2 :     return false;
     197                 :            :   }
     198                 :            : 
     199                 :       1150 :   return true;
     200                 :            : }
     201                 :            : 
     202                 :         61 : bool NodeImpl::attach(class MessageLoop* message_loop) {
     203         [ +  + ]:         61 :   if VUNLIKELY (!message_loop) {
     204                 :          6 :     return false;
     205                 :            :   }
     206                 :            : 
     207                 :         55 :   MessageLoop* expected = nullptr;
     208                 :         55 :   return helper_->message_loop.compare_exchange_strong(expected, message_loop, std::memory_order_release,
     209                 :         55 :                                                        std::memory_order_relaxed);
     210                 :            : }
     211                 :            : 
     212                 :        772 : bool NodeImpl::detach() {
     213                 :        772 :   MessageLoop* message_loop = nullptr;
     214                 :            : 
     215                 :            :   {
     216         [ +  - ]:        772 :     std::lock_guard lock(helper_->post_mtx);
     217                 :            : 
     218                 :        772 :     message_loop = helper_->message_loop.exchange(nullptr, std::memory_order_acq_rel);
     219                 :        772 :   }
     220                 :            : 
     221         [ +  + ]:        772 :   if (!message_loop) {
     222                 :        721 :     return false;
     223                 :            :   }
     224                 :            : 
     225         [ +  - ]:         51 :   if (!message_loop->is_in_same_thread()) {
     226                 :         51 :     message_loop->wait_for_idle();
     227                 :            :   }
     228                 :            : 
     229                 :         51 :   return true;
     230                 :            : }
     231                 :            : 
     232                 :       9723 : class MessageLoop* NodeImpl::get_message_loop() const { return helper_->message_loop.load(std::memory_order_acquire); }
     233                 :            : 
     234                 :         29 : void NodeImpl::register_status_handler(StatusCallback&& callback) {
     235   [ +  +  +  +  :         29 :   if VUNLIKELY (transport_type != TransportType::kDds && transport_type != TransportType::kDdsc &&
          +  +  +  +  +  
                      + ]
     236                 :            :                 transport_type != TransportType::kDdsr) {
     237   [ +  -  +  -  :         10 :     VLOG_W("Function [register_status_handler] is not supported.");
                   +  - ]
     238                 :          5 :     return;
     239                 :            :   }
     240                 :            : 
     241         [ +  - ]:         24 :   std::lock_guard lock(helper_->status_mtx);
     242                 :         24 :   helper_->status_callback = std::move(callback);
     243                 :         24 : }
     244                 :            : 
     245                 :        964 : bool NodeImpl::has_register_status() const {
     246   [ +  +  +  +  :        964 :   if VUNLIKELY (transport_type != TransportType::kDds && transport_type != TransportType::kDdsc &&
          +  +  +  +  +  
                      + ]
     247                 :            :                 transport_type != TransportType::kDdsr) {
     248   [ +  -  +  -  :         12 :     VLOG_W("Function [has_register_status] is not supported.");
                   +  - ]
     249                 :          6 :     return false;
     250                 :            :   }
     251                 :            : 
     252         [ +  - ]:        958 :   std::shared_lock lock(helper_->status_mtx);
     253                 :            : 
     254                 :        958 :   return helper_->status_callback != nullptr;
     255                 :        958 : }
     256                 :            : 
     257                 :         29 : void NodeImpl::call_status(Status::BasePtr ptr) {
     258   [ +  +  -  +  :         29 :   if VUNLIKELY (transport_type != TransportType::kDds && transport_type != TransportType::kDdsc &&
          -  +  -  -  -  
                      + ]
     259                 :            :                 transport_type != TransportType::kDdsr) {
     260   [ #  #  #  #  :          0 :     VLOG_W("Function [call_status] is not supported.");
                   #  # ]
     261                 :          1 :     return;
     262                 :            :   }
     263                 :            : 
     264                 :            :   {
     265         [ +  - ]:         29 :     std::lock_guard post_lock(helper_->post_mtx);
     266                 :            : 
     267                 :         29 :     auto* message_loop = helper_->message_loop.load(std::memory_order_acquire);
     268                 :            : 
     269         [ +  + ]:         29 :     if VLIKELY (message_loop) {
     270   [ +  -  +  - ]:          1 :       message_loop->post_task([this, ptr]() mutable {
     271         [ +  - ]:          1 :         std::shared_lock lock(helper_->status_mtx);
     272         [ +  - ]:          1 :         if VLIKELY (helper_->status_callback) {
     273         [ +  - ]:          1 :           helper_->status_callback(std::move(ptr));
     274                 :            :         }
     275                 :          1 :       });
     276                 :          1 :       return;
     277                 :            :     }
     278         [ +  + ]:         29 :   }
     279                 :            : 
     280         [ +  - ]:         28 :   std::shared_lock lock(helper_->status_mtx);
     281                 :            : 
     282         [ +  - ]:         28 :   if VLIKELY (helper_->status_callback) {
     283         [ +  - ]:         28 :     helper_->status_callback(std::move(ptr));
     284                 :            :   }
     285                 :         28 : }
     286                 :            : 
     287                 :        347 : void NodeImpl::set_property(const std::string& prop, const std::string& value) {
     288         [ +  - ]:        347 :   std::lock_guard lock(helper_->mtx);
     289   [ +  -  +  - ]:        347 :   helper_->property_map[prop] = value;
     290                 :        347 : }
     291                 :            : 
     292                 :        346 : std::string NodeImpl::get_property(const std::string& prop) const {
     293         [ +  - ]:        346 :   std::shared_lock lock(helper_->mtx);
     294                 :            : 
     295         [ +  - ]:        346 :   auto iter = helper_->property_map.find(prop);
     296                 :            : 
     297         [ +  + ]:        346 :   if VLIKELY (iter != helper_->property_map.end()) {
     298         [ +  - ]:        237 :     return iter->second;
     299                 :            :   }
     300                 :            : 
     301                 :        109 :   return {};
     302                 :        346 : }
     303                 :            : 
     304                 :        476 : Conf::PropertiesMap NodeImpl::get_all_properties() const {
     305         [ +  - ]:        476 :   std::shared_lock lock(helper_->mtx);
     306         [ +  - ]:        952 :   return helper_->property_map;
     307                 :        476 : }
     308                 :            : 
     309                 :         34 : void NodeImpl::set_discovery_enabled(bool enable) { is_discovery_enabled = enable; }
     310                 :            : 
     311                 :          5 : bool NodeImpl::get_discovery_enabled() const { return is_discovery_enabled; }
     312                 :            : 
     313                 :          1 : void NodeImpl::set_record_path(const std::string& path) {
     314                 :          1 :   std::shared_ptr<BagWriter> new_recorder;
     315                 :            : 
     316         [ -  + ]:          1 :   if (!path.empty()) {
     317         [ #  # ]:          0 :     new_recorder = BagWriter::filter_get(path);
     318                 :            :   }
     319                 :            : 
     320                 :          1 :   std::shared_ptr<BagWriter> old_recorder;
     321                 :            : 
     322                 :            :   {
     323         [ +  - ]:          1 :     std::lock_guard lock(helper_->mtx);
     324                 :          1 :     old_recorder = std::move(helper_->data_recorder);
     325                 :          1 :     helper_->data_recorder = std::move(new_recorder);
     326                 :          1 :     helper_->data_recorder_enabled.store(helper_->data_recorder != nullptr, std::memory_order_release);
     327                 :          1 :   }
     328                 :            : 
     329                 :          1 :   old_recorder.reset();
     330                 :          1 : }
     331                 :            : 
     332                 :          0 : bool NodeImpl::enable_security(const Security::Config& cfg) {
     333         [ #  # ]:          0 :   auto sec_cfg = cfg;
     334                 :            : 
     335         [ #  # ]:          0 :   return enable_security(std::move(sec_cfg));
     336                 :          0 : }
     337                 :            : 
     338                 :         49 : bool NodeImpl::enable_security(Security::Config&& cfg) {
     339   [ +  +  +  +  :         49 :   if VUNLIKELY (transport_type == TransportType::kIntra || (transport_type == TransportType::kDds && is_cdr_type)) {
          -  +  -  +  +  
                      + ]
     340   [ +  -  +  -  :          6 :     VLOG_W("Security::Config will ignore intra/dds(cdr) transport.");
                   +  - ]
     341                 :          3 :     return false;
     342                 :            :   }
     343                 :            : 
     344         [ +  - ]:         46 :   if VLIKELY (cfg.advanced.aad_context.empty()) {
     345         [ +  - ]:         46 :     cfg.advanced.aad_context = url;
     346         [ +  - ]:         46 :     cfg.advanced.aad_context += "|";
     347         [ +  - ]:         46 :     cfg.advanced.aad_context += ser_type;
     348         [ +  - ]:         46 :     cfg.advanced.aad_context += "|";
     349   [ +  -  +  - ]:         46 :     cfg.advanced.aad_context += std::to_string(static_cast<uint32_t>(schema_type));
     350                 :            :   }
     351                 :            : 
     352         [ +  - ]:         46 :   auto candidate = std::make_unique<Security>(std::move(cfg));
     353                 :            : 
     354         [ -  + ]:         46 :   if VUNLIKELY (!candidate->is_configured()) {
     355                 :            :     VLOG_W("Security::Config has no usable slot.");  // LCOV_EXCL_LINE GCOVR_EXCL_LINE
     356                 :            :     return false;                                    // LCOV_EXCL_LINE GCOVR_EXCL_LINE
     357                 :            :   }
     358                 :            : 
     359   [ +  +  +  + ]:         46 :   bool needs_encrypt = (impl_type == kPublisher || impl_type == kSetter);
     360   [ +  +  +  + ]:         46 :   bool needs_decrypt = (impl_type == kSubscriber || impl_type == kGetter);
     361                 :            : 
     362                 :            : #if defined(NDEBUG) || defined(__ANDROID__)
     363                 :            :   if (impl_type == kClient) {
     364                 :            :     needs_encrypt = true;
     365                 :            :     const auto* client_impl = static_cast<const ClientImpl*>(this);
     366                 :            :     needs_decrypt = client_impl != nullptr && client_impl->is_resp_type;
     367                 :            :   } else if (impl_type == kServer) {
     368                 :            :     needs_decrypt = true;
     369                 :            :     const auto* server_impl = static_cast<const ServerImpl*>(this);
     370                 :            :     needs_encrypt = server_impl != nullptr && server_impl->is_resp_type;
     371                 :            :   }
     372                 :            : #else
     373         [ +  + ]:         46 :   if (impl_type == kClient) {
     374                 :          7 :     needs_encrypt = true;
     375         [ +  - ]:          7 :     const auto* client_impl = dynamic_cast<const ClientImpl*>(this);
     376   [ +  -  +  - ]:          7 :     needs_decrypt = client_impl != nullptr && client_impl->is_resp_type;
     377         [ +  + ]:         39 :   } else if (impl_type == kServer) {
     378                 :          8 :     needs_decrypt = true;
     379         [ +  - ]:          8 :     const auto* server_impl = dynamic_cast<const ServerImpl*>(this);
     380   [ +  -  +  - ]:          8 :     needs_encrypt = server_impl != nullptr && server_impl->is_resp_type;
     381                 :            :   }
     382                 :            : #endif
     383                 :            : 
     384   [ +  +  -  +  :         46 :   if VUNLIKELY (needs_encrypt && !candidate->can_encrypt()) {
                   -  + ]
     385                 :            :     VLOG_W("Security::Config cannot encrypt for this sender role.");  // LCOV_EXCL_LINE GCOVR_EXCL_LINE
     386                 :            :     return false;                                                     // LCOV_EXCL_LINE GCOVR_EXCL_LINE
     387                 :            :   }
     388                 :            : 
     389   [ +  +  -  +  :         46 :   if VUNLIKELY (needs_decrypt && !candidate->can_decrypt()) {
                   -  + ]
     390                 :            :     VLOG_W("Security::Config cannot decrypt for this receiver role.");  // LCOV_EXCL_LINE GCOVR_EXCL_LINE
     391                 :            :     return false;                                                       // LCOV_EXCL_LINE GCOVR_EXCL_LINE
     392                 :            :   }
     393                 :            : 
     394                 :         46 :   security = std::move(candidate);
     395                 :            : 
     396                 :         46 :   return true;
     397                 :         46 : }
     398                 :            : 
     399                 :          1 : void NodeImpl::set_ssl_options(const SslOptions& options) {
     400         [ +  - ]:          1 :   std::lock_guard lock(helper_->mtx);
     401                 :          1 :   options.parse_to(helper_->property_map);
     402                 :          1 : }
     403                 :            : 
     404                 :      11018 : void NodeImpl::try_record(ActionType action_type, const Bytes& data) {
     405         [ +  - ]:      11018 :   auto* global_recorder = BagWriter::global_get();
     406                 :      11011 :   const bool data_recorder_enabled = helper_->data_recorder_enabled.load(std::memory_order_acquire);
     407                 :            : 
     408   [ +  +  +  #  :      11013 :   if VLIKELY (!global_recorder && !data_recorder_enabled) {
                   +  # ]
     409                 :      11015 :     return;
     410                 :            :   }
     411                 :            : 
     412                 :          0 :   std::shared_ptr<BagWriter> data_recorder;
     413                 :            : 
     414         [ -  # ]:          0 :   if (data_recorder_enabled) {
     415         [ #  # ]:          0 :     std::shared_lock lock(helper_->mtx);
     416                 :          0 :     data_recorder = helper_->data_recorder;
     417                 :          0 :   }
     418                 :            : 
     419   [ #  #  #  #  :          0 :   if VLIKELY (!global_recorder && !data_recorder) {
                   #  # ]
     420                 :          0 :     return;
     421                 :            :   }
     422                 :            : 
     423                 :            :   if constexpr (kIgnoreIntraUrl) {
     424                 :            :     if (transport_type == TransportType::kIntra) {
     425                 :            :       return;
     426                 :            :     }
     427                 :            :   }
     428                 :            : 
     429                 :          0 :   Frame frame;
     430                 :          0 :   frame.timestamp = -1;
     431         [ #  # ]:          0 :   frame.url = url;
     432         [ #  # ]:          0 :   frame.ser_type = ser_type;
     433                 :          0 :   frame.schema_type = schema_type;
     434                 :            : 
     435   [ #  #  #  # ]:          0 :   if (action_type == ActionType::kPublish && init_impl_type == kSetter) {
     436                 :          0 :     frame.action_type = ActionType::kSet;
     437   [ #  #  #  # ]:          0 :   } else if (action_type == ActionType::kSubscribe && init_impl_type == kGetter) {
     438                 :          0 :     frame.action_type = ActionType::kGet;
     439                 :            :   } else {
     440                 :          0 :     frame.action_type = action_type;
     441                 :            :   }
     442                 :            : 
     443                 :          0 :   frame.data = Bytes::shallow_copy(data.data(), data.size());
     444                 :            : 
     445         [ #  # ]:          0 :   if VUNLIKELY (global_recorder) {
     446         [ #  # ]:          0 :     global_recorder->push(frame);
     447                 :            :   }
     448                 :            : 
     449         [ #  # ]:          0 :   if VUNLIKELY (data_recorder) {
     450         [ #  # ]:          0 :     data_recorder->push(frame);
     451                 :            :   }
     452         [ #  # ]:          0 : }
     453                 :            : 
     454                 :        174 : void NodeImpl::reset_interrupted() { helper_->is_interrupted.store(false, std::memory_order_release); }
     455                 :            : 
     456                 :        337 : bool NodeImpl::is_interrupted() const { return helper_->is_interrupted.load(std::memory_order_acquire); }
     457                 :            : 
     458                 :       1160 : void NodeImpl::init_ext() {
     459         [ +  + ]:       1160 :   if (should_report_discovery(*this)) {
     460                 :        507 :     auto* global_reporter = GlobalDiscoveryReporter::get();
     461                 :            : 
     462         [ +  - ]:        507 :     if (global_reporter) {
     463   [ -  +  -  -  :        507 :       if (CpuProfiler::is_global_enabled() && !profiler) {
                   -  + ]
     464                 :            :         profiler = std::make_unique<CpuProfiler>();  // LCOV_EXCL_LINE GCOVR_EXCL_LINE
     465                 :            :       }
     466                 :            : 
     467                 :        507 :       global_reporter->add(this);
     468                 :            :     }
     469                 :            :   }
     470                 :            : 
     471                 :            : #ifdef VLINK_ENABLE_CHECK_LICENSE
     472                 :            :   [[maybe_unused]] static LicenseCheck license;
     473                 :            : #endif
     474                 :       1160 : }
     475                 :            : 
     476                 :       1160 : void NodeImpl::deinit_ext() {
     477         [ +  + ]:       1160 :   if (!should_report_discovery(*this)) {
     478                 :        653 :     return;
     479                 :            :   }
     480                 :            : 
     481                 :        507 :   auto* global_reporter = GlobalDiscoveryReporter::get(false);
     482                 :            : 
     483         [ +  - ]:        507 :   if (global_reporter) {
     484                 :        507 :     global_reporter->remove(this);
     485                 :            : 
     486   [ -  +  -  -  :        507 :     if (CpuProfiler::is_global_enabled() && profiler) {
                   -  + ]
     487                 :            :       profiler->restart();  // LCOV_EXCL_LINE GCOVR_EXCL_LINE
     488                 :            :     }
     489                 :            :   }
     490                 :            : }
     491                 :            : 
     492                 :       1404 : void NodeImpl::global_init() {
     493                 :            : #ifdef VLINK_ENABLE_SECURITY
     494                 :            :   [[maybe_unused]] static const int kOpenSslInitialized =
     495   [ +  +  +  -  :       1404 :       OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS, nullptr);
             +  -  -  - ]
     496                 :            : #endif
     497                 :            : 
     498                 :       1404 :   Logger::get();
     499                 :            : 
     500                 :       1403 :   Bytes::init_memory_pool();
     501                 :            : 
     502                 :       1404 :   BagWriter::global_get();
     503                 :            : 
     504                 :       1404 :   GlobalDiscoveryReporter::get(false);
     505                 :       1404 : }
     506                 :            : 
     507         [ +  - ]:       1401 : NodeImpl::NodeImpl(ImplType type) : impl_type(type), init_impl_type(type), helper_(std::make_unique<NodeImplHelper>()) {
     508         [ +  - ]:       1401 :   global_init();
     509                 :       1401 : }
     510                 :            : 
     511                 :       1401 : NodeImpl::~NodeImpl() = default;
     512                 :            : 
     513                 :            : }  // namespace vlink

Generated by: LCOV version 1.14