int nn_rep_recv (struct nn_sockbase *self, struct nn_msg *msg) { int rc; struct nn_rep *rep; rep = nn_cont (self, struct nn_rep, xrep.sockbase); /* If a request is already being processed, cancel it. */ if (nn_slow (rep->flags & NN_REP_INPROGRESS)) { nn_chunkref_term (&rep->backtrace); rep->flags &= ~NN_REP_INPROGRESS; } /* Receive the request. */ rc = nn_xrep_recv (&rep->xrep.sockbase, msg); if (nn_slow (rc == -EAGAIN)) return -EAGAIN; errnum_assert (rc == 0, -rc); /* Store the backtrace. */ nn_chunkref_mv (&rep->backtrace, &msg->sphdr); nn_chunkref_init (&msg->sphdr, 0); rep->flags |= NN_REP_INPROGRESS; return 0; }
int nn_rep_send (struct nn_sockbase *self, struct nn_msg *msg) { int rc; struct nn_rep *rep; rep = nn_cont (self, struct nn_rep, xrep.sockbase); /* If no request was received, there's nowhere to send the reply to. */ if (nn_slow (!(rep->flags & NN_REP_INPROGRESS))) return -EFSM; /* Move the stored backtrace into the message header. */ nn_assert (nn_chunkref_size (&msg->sphdr) == 0); nn_chunkref_term (&msg->sphdr); nn_chunkref_mv (&msg->sphdr, &rep->backtrace); rep->flags &= ~NN_REP_INPROGRESS; /* Send the reply. If it cannot be sent because of pushback, drop it silently. */ rc = nn_xrep_send (&rep->xrep.sockbase, msg); errnum_assert (rc == 0 || rc == -EAGAIN, -rc); return 0; }
void nn_msg_mv (struct nn_msg *dst, struct nn_msg *src) { nn_chunkref_mv (&dst->hdr, &src->hdr); nn_chunkref_mv (&dst->body, &src->body); }