LCOV - code coverage report
Current view: top level - src/util - wpipe.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 33 41 80.5 %
Date: 2026-06-25 07:23:43 Functions: 7 7 100.0 %

          Line data    Source code
       1             : // Copyright (c) 2020-2025 The Dash Core developers
       2             : // Distributed under the MIT software license, see the accompanying
       3             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       4             : 
       5             : #include <util/wpipe.h>
       6             : 
       7             : #include <logging.h>
       8             : #include <util/edge.h>
       9             : #include <util/sock.h>
      10             : 
      11             : static constexpr int EXPECTED_PIPE_WRITTEN_BYTES = 1;
      12             : 
      13        5642 : WakeupPipe::WakeupPipe(EdgeTriggeredEvents* edge_trig_events)
      14             :     : m_edge_trig_events{edge_trig_events}
      15        2821 : {
      16             : #ifdef USE_WAKEUP_PIPE
      17             :     if (pipe(m_pipe.data()) != 0) {
      18             :         LogPrintf("Unable to initialize WakeupPipe, pipe() for m_pipe failed with error %s\n",
      19             :                   NetworkErrorString(WSAGetLastError()));
      20             :         return;
      21             :     }
      22             :     for (size_t idx = 0; idx < m_pipe.size(); idx++) {
      23             :         int flags = fcntl(m_pipe[idx], F_GETFL, 0);
      24             :         if (fcntl(m_pipe[idx], F_SETFL, flags | O_NONBLOCK) == SOCKET_ERROR) {
      25             :             LogPrintf("Unable to initialize WakeupPipe, fcntl for O_NONBLOCK on m_pipe[%d] failed with error %s\n", idx,
      26             :                       NetworkErrorString(WSAGetLastError()));
      27             :             Close();
      28             :             return;
      29             :         }
      30             :     }
      31             :     if (edge_trig_events && !edge_trig_events->RegisterPipe(m_pipe[0])) {
      32             :         LogPrintf("Unable to initialize WakeupPipe, EdgeTriggeredEvents::RegisterPipe() failed for m_pipe[0] = %d\n",
      33             :                   m_pipe[0]);
      34             :         Close();
      35             :         return;
      36             :     }
      37             :     m_valid = true;
      38             : #else
      39             :     LogPrintf("Attempting to initialize WakeupPipe without support compiled in!\n");
      40             : #endif /* USE_WAKEUP_PIPE */
      41        2821 : }
      42             : 
      43        5642 : WakeupPipe::~WakeupPipe()
      44        2821 : {
      45        2821 :     if (m_valid) {
      46             : #ifdef USE_WAKEUP_PIPE
      47        2821 :         Drain();
      48        2821 :         if (m_edge_trig_events && !m_edge_trig_events->UnregisterPipe(m_pipe[0])) {
      49           0 :             LogPrintf("Destroying WakeupPipe instance, EdgeTriggeredEvents::UnregisterPipe() failed for m_pipe[0] = %d\n",
      50             :                       m_pipe[0]);
      51           0 :         }
      52        2821 :         Close();
      53             : #else
      54             :         assert(false);
      55             : #endif /* USE_WAKEUP_PIPE */
      56        2821 :     }
      57        5642 : }
      58             : 
      59        2821 : void WakeupPipe::Close()
      60             : {
      61             : #ifdef USE_WAKEUP_PIPE
      62        8463 :     for (size_t idx{0}; idx < m_pipe.size(); idx++) {
      63        5642 :         if (m_pipe[idx] != -1 && close(m_pipe[idx]) != 0) {
      64           0 :             LogPrintf("close() failed for m_pipe[%d] = %d with error %s\n", idx, m_pipe[idx],
      65             :                       NetworkErrorString(WSAGetLastError()));
      66           0 :         }
      67        5642 :         m_pipe[idx] = -1;
      68        5642 :     }
      69             : #else
      70             :     assert(false);
      71             : #endif /* USE_WAKEUP_PIPE */
      72        2821 : }
      73             : 
      74      523251 : void WakeupPipe::Drain() const
      75             : {
      76             : #ifdef USE_WAKEUP_PIPE
      77      523251 :     assert(m_valid && m_pipe[0] != -1);
      78             : 
      79      523251 :     int ret{0};
      80      523251 :     std::array<uint8_t, 128> buf{};
      81      523251 :     do {
      82     1043739 :         ret = read(m_pipe[0], buf.data(), buf.size());
      83     1043739 :     } while (ret > 0);
      84             : #else
      85             :     assert(false);
      86             : #endif /* USE_WAKEUP_PIPE */
      87      523251 : }
      88             : 
      89      521643 : void WakeupPipe::Write()
      90             : {
      91             : #ifdef USE_WAKEUP_PIPE
      92      521643 :     assert(m_valid && m_pipe[1] != -1);
      93             : 
      94      521643 :     std::array<uint8_t, EXPECTED_PIPE_WRITTEN_BYTES> buf{};
      95      521643 :     int ret = write(m_pipe[1], buf.data(), buf.size());
      96      521643 :     if (ret == SOCKET_ERROR) {
      97           0 :         LogPrintf("write() to m_pipe[1] = %d failed with error %s\n", m_pipe[1], NetworkErrorString(WSAGetLastError()));
      98           0 :     }
      99      521643 :     if (ret != EXPECTED_PIPE_WRITTEN_BYTES) {
     100           0 :         LogPrintf("write() to m_pipe[1] = %d succeeded with unexpected result %d (expected %d)\n", m_pipe[1], ret,
     101             :                   EXPECTED_PIPE_WRITTEN_BYTES);
     102           0 :     }
     103             : 
     104      521643 :     m_need_wakeup = false;
     105             : #else
     106             :     assert(false);
     107             : #endif /* USE_WAKEUP_PIPE */
     108      521643 : }

Generated by: LCOV version 1.16