static struct nn_chunk *nn_chunk_getptr (void *p) { uint32_t off; nn_assert (nn_getl ((uint8_t*) p - sizeof (uint32_t)) == NN_CHUNK_TAG); off = nn_getl ((uint8_t*) p - 2 * sizeof (uint32_t)); return (struct nn_chunk*) ((uint8_t*) p - 2 *sizeof (uint32_t) - off - sizeof (struct nn_chunk)); }
static int nn_respondent_recv (struct nn_sockbase *self, struct nn_msg *msg) { int rc; struct nn_respondent *respondent; respondent = nn_cont (self, struct nn_respondent, xrespondent.sockbase); /* Cancel current survey, if it exists. */ respondent->flags &= ~NN_RESPONDENT_INPROGRESS; /* Get next survey. */ rc = nn_xrespondent_recv (&respondent->xrespondent.sockbase, msg); if (nn_slow (rc == -EAGAIN)) return -EAGAIN; errnum_assert (rc == 0, -rc); /* Remember the survey ID. */ nn_assert (nn_chunkref_size (&msg->sphdr) == sizeof (uint32_t)); respondent->surveyid = nn_getl (nn_chunkref_data (&msg->sphdr)); nn_chunkref_term (&msg->sphdr); nn_chunkref_init (&msg->sphdr, 0); /* Remember that survey is being processed. */ respondent->flags |= NN_RESPONDENT_INPROGRESS; return 0; }
void nn_req_in (struct nn_sockbase *self, struct nn_pipe *pipe) { int rc; struct nn_req *req; uint32_t reqid; req = nn_cont (self, struct nn_req, xreq.sockbase); /* Pass the pipe to the raw REQ socket. */ nn_xreq_in (&req->xreq.sockbase, pipe); while (1) { /* Get new reply. */ rc = nn_xreq_recv (&req->xreq.sockbase, &req->task.reply); if (nn_slow (rc == -EAGAIN)) return; errnum_assert (rc == 0, -rc); /* No request was sent. Getting a reply doesn't make sense. */ if (nn_slow (!nn_req_inprogress (req))) { nn_msg_term (&req->task.reply); continue; } /* Ignore malformed replies. */ if (nn_slow (nn_chunkref_size (&req->task.reply.sphdr) != sizeof (uint32_t))) { nn_msg_term (&req->task.reply); continue; } /* Ignore replies with incorrect request IDs. */ reqid = nn_getl (nn_chunkref_data (&req->task.reply.sphdr)); if (nn_slow (!(reqid & 0x80000000))) { nn_msg_term (&req->task.reply); continue; } if (nn_slow (reqid != (req->task.id | 0x80000000))) { nn_msg_term (&req->task.reply); continue; } /* Trim the request ID. */ nn_chunkref_term (&req->task.reply.sphdr); nn_chunkref_init (&req->task.reply.sphdr, 0); /* TODO: Deallocate the request here? */ /* Notify the state machine. */ if (req->state == NN_REQ_STATE_ACTIVE) nn_fsm_action (&req->fsm, NN_REQ_ACTION_IN); return; } }
static void nn_req_in (struct nn_sockbase *self, struct nn_pipe *pipe) { int rc; struct nn_req *req; uint32_t reqid; req = nn_cont (self, struct nn_req, xreq.sockbase); /* Pass the pipe to the raw REQ socket. */ nn_xreq_in (&req->xreq.sockbase, pipe); while (1) { /* Get new reply. */ rc = nn_xreq_recv (&req->xreq.sockbase, &req->reply); if (nn_slow (rc == -EAGAIN)) return; errnum_assert (rc == 0, -rc); /* No request was sent. Getting a reply doesn't make sense. */ if (nn_slow (req->state != NN_REQ_STATE_SENT)) { nn_msg_term (&req->reply); continue; } /* Ignore malformed replies. */ if (nn_slow (nn_chunkref_size (&req->reply.hdr) != sizeof (uint32_t))) { nn_msg_term (&req->reply); continue; } /* Ignore replies with incorrect request IDs. */ reqid = nn_getl (nn_chunkref_data (&req->reply.hdr)); if (nn_slow (!(reqid & 0x80000000))) { nn_msg_term (&req->reply); continue; } if (nn_slow (reqid != (req->reqid | 0x80000000))) { nn_msg_term (&req->reply); continue; } /* Trim the request ID. */ nn_chunkref_term (&req->reply.hdr); nn_chunkref_init (&req->reply.hdr, 0); /* Swtich to RECEIVED state. */ nn_timer_stop (&req->resend_timer); nn_msg_term (&req->request); req->state = NN_REQ_STATE_RECEIVED; return; } }
static int nn_surveyor_recv (struct nn_sockbase *self, struct nn_msg *msg) { int rc; struct nn_surveyor *surveyor; uint32_t surveyid; surveyor = nn_cont (self, struct nn_surveyor, xsurveyor.sockbase); /* If no survey is going on return EFSM error. */ if (nn_slow (!nn_surveyor_inprogress (surveyor))) { if (surveyor->timedout == NN_SURVEYOR_TIMEDOUT) { surveyor->timedout = 0; return -ETIMEDOUT; } else return -EFSM; } while (1) { /* Get next response. */ rc = nn_xsurveyor_recv (&surveyor->xsurveyor.sockbase, msg); if (nn_slow (rc == -EAGAIN)) return -EAGAIN; errnum_assert (rc == 0, -rc); /* Get the survey ID. Ignore any stale responses. */ /* TODO: This should be done asynchronously! */ if (nn_slow (nn_chunkref_size (&msg->sphdr) != sizeof (uint32_t))) continue; surveyid = nn_getl (nn_chunkref_data (&msg->sphdr)); if (nn_slow (surveyid != surveyor->surveyid)) continue; /* Discard the header and return the message to the user. */ nn_chunkref_term (&msg->sphdr); nn_chunkref_init (&msg->sphdr, 0); break; } return 0; }
static int nn_surveyor_recv (struct nn_sockbase *self, struct nn_msg *msg) { int rc; struct nn_surveyor *surveyor; uint32_t surveyid; surveyor = nn_cont (self, struct nn_surveyor, xsurveyor.sockbase); /* If no survey is going on return EFSM error. */ if (nn_slow (!(surveyor->flags & NN_SURVEYOR_INPROGRESS))) return -EFSM; while (1) { /* Get next response. */ rc = nn_xsurveyor_recv (&surveyor->xsurveyor.sockbase, msg); if (nn_slow (rc == -EAGAIN)) return -EAGAIN; errnum_assert (rc == 0, -rc); /* Get the survey ID. Ignore any stale responses. */ if (nn_slow (nn_chunkref_size (&msg->hdr) != sizeof (uint32_t))) { nn_msg_term (msg); continue; } surveyid = nn_getl (nn_chunkref_data (&msg->hdr)); if (nn_slow (surveyid != surveyor->surveyid)) { nn_msg_term (msg); continue; } /* Discard the header and return the message to the user. */ nn_chunkref_term (&msg->hdr); nn_chunkref_init (&msg->hdr, 0); break; } return 0; }