Coverage Report

Created: 2026-08-13 06:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libzmq/src/reaper.cpp
Line
Count
Source
1
/* SPDX-License-Identifier: MPL-2.0 */
2
3
#include "precompiled.hpp"
4
#include "macros.hpp"
5
#include <new>
6
#include "reaper.hpp"
7
#include "socket_base.hpp"
8
#include "err.hpp"
9
10
zmq::reaper_t::reaper_t (class ctx_t *ctx_, uint32_t tid_) :
11
976
    object_t (ctx_, tid_),
12
976
    _mailbox_handle (static_cast<poller_t::handle_t> (NULL)),
13
976
    _poller (NULL),
14
976
    _sockets (0),
15
976
    _terminating (false)
16
976
{
17
976
    if (!_mailbox.valid ())
18
0
        return;
19
20
976
    _poller = new (std::nothrow) poller_t (*ctx_);
21
976
    alloc_assert (_poller);
22
23
976
    if (_mailbox.get_fd () != retired_fd) {
24
976
        _mailbox_handle = _poller->add_fd (_mailbox.get_fd (), this);
25
976
        _poller->set_pollin (_mailbox_handle);
26
976
    }
27
28
976
#ifdef HAVE_FORK
29
976
    _pid = getpid ();
30
976
#endif
31
976
}
32
33
zmq::reaper_t::~reaper_t ()
34
976
{
35
976
    LIBZMQ_DELETE (_poller);
36
976
}
37
38
zmq::mailbox_t *zmq::reaper_t::get_mailbox ()
39
2.92k
{
40
2.92k
    return &_mailbox;
41
2.92k
}
42
43
void zmq::reaper_t::start ()
44
976
{
45
976
    zmq_assert (_mailbox.valid ());
46
47
    //  Start the thread.
48
976
    _poller->start ("Reaper");
49
976
}
50
51
void zmq::reaper_t::stop ()
52
976
{
53
976
    if (get_mailbox ()->valid ()) {
54
976
        send_stop ();
55
976
    }
56
976
}
57
58
void zmq::reaper_t::in_event ()
59
976
{
60
3.90k
    while (true) {
61
3.90k
#ifdef HAVE_FORK
62
3.90k
        if (unlikely (_pid != getpid ())) {
63
            //printf("zmq::reaper_t::in_event return in child process %d\n", (int)getpid());
64
0
            return;
65
0
        }
66
3.90k
#endif
67
68
        //  Get the next command. If there is none, exit.
69
3.90k
        command_t cmd;
70
3.90k
        const int rc = _mailbox.recv (&cmd, 0);
71
3.90k
        if (rc != 0 && errno == EINTR)
72
0
            continue;
73
3.90k
        if (rc != 0 && errno == EAGAIN)
74
976
            break;
75
2.92k
        errno_assert (rc == 0);
76
77
        //  Process the command.
78
2.92k
        cmd.destination->process_command (cmd);
79
2.92k
    }
80
976
}
81
82
void zmq::reaper_t::out_event ()
83
0
{
84
0
    zmq_assert (false);
85
0
}
86
87
void zmq::reaper_t::timer_event (int)
88
0
{
89
0
    zmq_assert (false);
90
0
}
91
92
void zmq::reaper_t::process_stop ()
93
976
{
94
976
    _terminating = true;
95
96
    //  If there are no sockets being reaped finish immediately.
97
976
    if (!_sockets) {
98
1
        send_done ();
99
1
        _poller->rm_fd (_mailbox_handle);
100
1
        _poller->stop ();
101
1
    }
102
976
}
103
104
void zmq::reaper_t::process_reap (socket_base_t *socket_)
105
976
{
106
    //  Add the socket to the poller.
107
976
    socket_->start_reaping (_poller);
108
109
976
    ++_sockets;
110
976
}
111
112
void zmq::reaper_t::process_reaped ()
113
976
{
114
976
    --_sockets;
115
116
    //  If reaped was already asked to terminate and there are no more sockets,
117
    //  finish immediately.
118
976
    if (!_sockets && _terminating) {
119
975
        send_done ();
120
975
        _poller->rm_fd (_mailbox_handle);
121
975
        _poller->stop ();
122
975
    }
123
976
}