Coverage Report

Created: 2026-01-10 06:17

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libzmq/src/rep.cpp
Line
Count
Source
1
/* SPDX-License-Identifier: MPL-2.0 */
2
3
#include "precompiled.hpp"
4
#include "rep.hpp"
5
#include "err.hpp"
6
#include "msg.hpp"
7
8
zmq::rep_t::rep_t (class ctx_t *parent_, uint32_t tid_, int sid_) :
9
0
    router_t (parent_, tid_, sid_),
10
0
    _sending_reply (false),
11
0
    _request_begins (true)
12
0
{
13
0
    options.type = ZMQ_REP;
14
0
}
15
16
zmq::rep_t::~rep_t ()
17
0
{
18
0
}
19
20
int zmq::rep_t::xsend (msg_t *msg_)
21
0
{
22
    //  If we are in the middle of receiving a request, we cannot send reply.
23
0
    if (!_sending_reply) {
24
0
        errno = EFSM;
25
0
        return -1;
26
0
    }
27
28
0
    const bool more = (msg_->flags () & msg_t::more) != 0;
29
30
    //  Push message to the reply pipe.
31
0
    const int rc = router_t::xsend (msg_);
32
0
    if (rc != 0)
33
0
        return rc;
34
35
    //  If the reply is complete flip the FSM back to request receiving state.
36
0
    if (!more)
37
0
        _sending_reply = false;
38
39
0
    return 0;
40
0
}
41
42
int zmq::rep_t::xrecv (msg_t *msg_)
43
0
{
44
    //  If we are in middle of sending a reply, we cannot receive next request.
45
0
    if (_sending_reply) {
46
0
        errno = EFSM;
47
0
        return -1;
48
0
    }
49
50
    //  First thing to do when receiving a request is to copy all the labels
51
    //  to the reply pipe.
52
0
    if (_request_begins) {
53
0
        while (true) {
54
0
            int rc = router_t::xrecv (msg_);
55
0
            if (rc != 0)
56
0
                return rc;
57
58
0
            if ((msg_->flags () & msg_t::more)) {
59
                //  Empty message part delimits the traceback stack.
60
0
                const bool bottom = (msg_->size () == 0);
61
62
                //  Push it to the reply pipe.
63
0
                rc = router_t::xsend (msg_);
64
0
                errno_assert (rc == 0);
65
66
0
                if (bottom)
67
0
                    break;
68
0
            } else {
69
                //  If the traceback stack is malformed, discard anything
70
                //  already sent to pipe (we're at end of invalid message).
71
0
                rc = router_t::rollback ();
72
0
                errno_assert (rc == 0);
73
0
            }
74
0
        }
75
0
        _request_begins = false;
76
0
    }
77
78
    //  Get next message part to return to the user.
79
0
    const int rc = router_t::xrecv (msg_);
80
0
    if (rc != 0)
81
0
        return rc;
82
83
    //  If whole request is read, flip the FSM to reply-sending state.
84
0
    if (!(msg_->flags () & msg_t::more)) {
85
0
        _sending_reply = true;
86
0
        _request_begins = true;
87
0
    }
88
89
0
    return 0;
90
0
}
91
92
bool zmq::rep_t::xhas_in ()
93
0
{
94
0
    if (_sending_reply)
95
0
        return false;
96
97
0
    return router_t::xhas_in ();
98
0
}
99
100
bool zmq::rep_t::xhas_out ()
101
0
{
102
0
    if (!_sending_reply)
103
0
        return false;
104
105
0
    return router_t::xhas_out ();
106
0
}