Example #1
0
static void nn_req_term (struct nn_req *self)
{
    nn_timer_term (&self->timer);
    nn_msg_term (&self->reply);
    nn_msg_term (&self->request);
    nn_fsm_term (&self->fsm);
    nn_xreq_term (&self->xreq);
}
Example #2
0
static void nn_req_term (struct nn_req *self)
{
    if (self->state == NN_REQ_STATE_UNSENT || self->state == NN_REQ_STATE_SENT)
        nn_msg_term (&self->request);
    if (self->state == NN_REQ_STATE_RECEIVED)
        nn_msg_term (&self->reply);
    nn_timer_term (&self->resend_timer);
    nn_xreq_term (&self->xreq);
}
Example #3
0
void nn_req_term (struct nn_req *self)
{
    nn_timer_term (&self->task.timer);
    nn_task_term (&self->task);
    nn_msg_term (&self->task.reply);
    nn_msg_term (&self->task.request);
    nn_fsm_term (&self->fsm);
    nn_xreq_term (&self->xreq);
}
Example #4
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;
    }
}
Example #5
0
void nn_stcp_term(struct nn_stcp *self)
{
    nn_assert_state(self,NN_STCP_STATE_IDLE);
    nn_fsm_event_term(&self->done);
    nn_msg_term(&self->outmsg);
    nn_msg_term(&self->inmsg);
    nn_pipebase_term(&self->pipebase);
    nn_streamhdr_term(&self->streamhdr);
    nn_fsm_term(&self->fsm);
}
Example #6
0
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;
    }
}
Example #7
0
void nn_slibfabric_term (struct nn_slibfabric *self)
{
    nn_assert_state (self, NN_SLIBFABRIC_STATE_IDLE);

    nn_fsm_event_term (&self->done);
    nn_msg_term (&self->outmsg);
    nn_msg_term (&self->inmsg);
    nn_pipebase_term (&self->pipebase);
    nn_streamhdr_term (&self->streamhdr);
    nn_fsm_term (&self->fsm);
}
Example #8
0
void nn_sipc_term (struct nn_sipc *self)
{
    nn_assert (self->state == NN_SIPC_STATE_IDLE);

    nn_fsm_event_term (&self->done);
    nn_msg_term (&self->outmsg);
    nn_msg_term (&self->inmsg);
    nn_pipebase_term (&self->pipebase);
    nn_streamhdr_term (&self->streamhdr);
    nn_fsm_term (&self->fsm);
}
Example #9
0
void nn_stream_term (struct nn_stream *self)
{
    /*  Close the messages in progress. */
    nn_msg_term (&self->inmsg);
    nn_msg_term (&self->outmsg);

    nn_timer_term (&self->hdr_timeout);
    nn_pipebase_term (&self->pipebase);

    /*  Return control to the parent state machine. */
    nn_usock_setsink (self->usock, self->original_sink);
}
Example #10
0
static int nn_req_send (struct nn_sockbase *self, struct nn_msg *msg)
{
    int rc;
    struct nn_req *req;

    req = nn_cont (self, struct nn_req, xreq.sockbase);

    /*  If there's a request in progress, cancel it. */
    if (nn_slow (req->state != NN_REQ_STATE_IDLE)) {
        if (req->state == NN_REQ_STATE_UNSENT ||
              req->state == NN_REQ_STATE_SENT)
            nn_msg_term (&req->request);
        if (req->state == NN_REQ_STATE_RECEIVED)
            nn_msg_term (&req->reply);
        nn_timer_term (&req->resend_timer);
        req->state = NN_REQ_STATE_IDLE;
    }

    /*  Generate new request ID for the new request and put it into message
        header. The most important bit is set to 1 to indicate that this is
        the bottom of the backtrace stack. */
    ++req->reqid;
    nn_assert (nn_chunkref_size (&msg->hdr) == 0);
    nn_chunkref_term (&msg->hdr);
    nn_chunkref_init (&msg->hdr, 4);
    nn_putl (nn_chunkref_data (&msg->hdr), req->reqid | 0x80000000);

    /*  Store the message so that it can be re-sent if there's no reply. 
        Then make a copy of it and send it. */
    nn_msg_cp (&req->request, msg);
    rc = nn_xreq_send (&req->xreq.sockbase, msg);
    errnum_assert (rc == 0 || rc == -EAGAIN, -rc);

    /*  If the request cannot be sent at the moment switch to UNSENT state.
        It will be sent as soon as a new outbound pipe arrives. */
    if (nn_slow (rc == -EAGAIN)) {
        nn_msg_term (msg);
        req->state = NN_REQ_STATE_UNSENT;
        return 0;
    }

    /*  If the request was successgfully sent set up the re-send timer in case
        it get lost somewhere further out in the topology. */
    nn_timer_start (&req->resend_timer, req->resend_ivl);
    req->state = NN_REQ_STATE_SENT;

    return 0;
}
Example #11
0
int nn_xreq_recv (struct nn_sockbase *self, struct nn_msg *msg)
{
    int rc;

    rc = nn_fq_recv (&nn_cont (self, struct nn_xreq, sockbase)->fq, msg, NULL);
    if (rc == -EAGAIN)
        return -EAGAIN;
    errnum_assert (rc >= 0, -rc);

    if (!(rc & NN_PIPE_PARSED)) {

        /*  Ignore malformed replies. */
        if (nn_slow (nn_chunkref_size (&msg->body) < sizeof (uint32_t))) {
            nn_msg_term (msg);
            return -EAGAIN;
        }

        /*  Split the message into the header and the body. */
        nn_assert (nn_chunkref_size (&msg->sphdr) == 0);
        nn_chunkref_term (&msg->sphdr);
        nn_chunkref_init (&msg->sphdr, sizeof (uint32_t));
        memcpy (nn_chunkref_data (&msg->sphdr), nn_chunkref_data (&msg->body),
            sizeof (uint32_t));
        nn_chunkref_trim (&msg->body, sizeof (uint32_t));
    }

    return 0;
}
Example #12
0
File: xsub.c Project: 4ker/nanomsg
static int nn_xsub_recv (struct nn_sockbase *self, struct nn_msg *msg)
{
    int rc;
    struct nn_xsub *xsub;

    xsub = nn_cont (self, struct nn_xsub, sockbase);

    /*  Loop while a matching message is found or when there are no more
        messages to receive. */
    while (1) {
        rc = nn_fq_recv (&xsub->fq, msg, NULL);
        if (nn_slow (rc == -EAGAIN))
            return -EAGAIN;
        errnum_assert (rc >= 0, -rc);
        rc = nn_trie_match (&xsub->trie, nn_chunkref_data (&msg->body),
            nn_chunkref_size (&msg->body));
        if (rc == 0) {
            nn_msg_term (msg);
            continue;
        }
        if (rc == 1)
            return 0;
        errnum_assert (0, -rc);
    }
}
Example #13
0
int nn_xbus_recv (struct nn_sockbase *self, struct nn_msg *msg)
{
    int rc;
    struct nn_xbus *xbus;
    struct nn_pipe *pipe;

    xbus = nn_cont (self, struct nn_xbus, sockbase);

    while (1) {

        /*  Get next message in fair-queued manner. */
        rc = nn_fq_recv (&xbus->inpipes, msg, &pipe);
        if (nn_slow (rc < 0))
            return rc;

        /*  The message should have no header. Drop malformed messages. */
        if (nn_chunkref_size (&msg->hdr) == 0)
            break;
        nn_msg_term (msg);
    }

    /*  Add pipe ID to the message header. */
    nn_chunkref_term (&msg->hdr);
    nn_chunkref_init (&msg->hdr, sizeof (uint64_t));
    memset (nn_chunkref_data (&msg->hdr), 0, sizeof (uint64_t));
    memcpy (nn_chunkref_data (&msg->hdr), &pipe, sizeof (pipe));

    return 0;
}
Example #14
0
static void nn_surveyor_term (struct nn_surveyor *self)
{
    nn_msg_term (&self->tosend);
    nn_timer_term (&self->timer);
    nn_fsm_term (&self->fsm);
    nn_xsurveyor_term (&self->xsurveyor);
}
Example #15
0
static int nn_sipc_send (struct nn_pipebase *self, struct nn_msg *msg)
{
    struct nn_sipc *sipc;
    struct nn_iovec iov [3];

    sipc = nn_cont (self, struct nn_sipc, pipebase);

    nn_assert (sipc->state == NN_SIPC_STATE_ACTIVE);
    nn_assert (sipc->outstate == NN_SIPC_OUTSTATE_IDLE);

    /*  Move the message to the local storage. */
    nn_msg_term (&sipc->outmsg);
    nn_msg_mv (&sipc->outmsg, msg);

    /*  Serialise the message header. */
    sipc->outhdr [0] = NN_SIPC_MSG_NORMAL;
    nn_putll (sipc->outhdr + 1, nn_chunkref_size (&sipc->outmsg.hdr) +
        nn_chunkref_size (&sipc->outmsg.body));

    /*  Start async sending. */
    iov [0].iov_base = sipc->outhdr;
    iov [0].iov_len = sizeof (sipc->outhdr);
    iov [1].iov_base = nn_chunkref_data (&sipc->outmsg.hdr);
    iov [1].iov_len = nn_chunkref_size (&sipc->outmsg.hdr);
    iov [2].iov_base = nn_chunkref_data (&sipc->outmsg.body);
    iov [2].iov_len = nn_chunkref_size (&sipc->outmsg.body);
    nn_usock_send (sipc->usock, iov, 3);

    sipc->outstate = NN_SIPC_OUTSTATE_SENDING;

    return 0;
}
Example #16
0
int nn_xsurveyor_recv (struct nn_sockbase *self, struct nn_msg *msg)
{
    int rc;
    struct nn_xsurveyor *xsurveyor;

    xsurveyor = nn_cont (self, struct nn_xsurveyor, sockbase);

    rc = nn_fq_recv (&xsurveyor->inpipes, msg, NULL);
    if (nn_slow (rc < 0))
        return rc;

    /*  Split the header from the body, if needed. */
    if (!(rc & NN_PIPE_PARSED)) {
        if (nn_slow (nn_chunkref_size (&msg->body) < sizeof (uint32_t))) {
            nn_msg_term (msg);
            return -EAGAIN;
        }
        nn_assert (nn_chunkref_size (&msg->hdr) == 0);
        nn_chunkref_term (&msg->hdr);
        nn_chunkref_init (&msg->hdr, sizeof (uint32_t));
        memcpy (nn_chunkref_data (&msg->hdr), nn_chunkref_data (&msg->body),
           sizeof (uint32_t));
        nn_chunkref_trim (&msg->body, sizeof (uint32_t));
    }

    return 0;
}
Example #17
0
static void nn_req_action_send (struct nn_req *self)
{
    int rc;
    struct nn_msg msg;

    /*  Send the request. */
    nn_msg_cp (&msg, &self->request);
    rc = nn_xreq_send (&self->xreq.sockbase, &msg);

    /*  If the request cannot be sent at the moment wait till
        new outbound pipe arrives. */
    if (nn_slow (rc == -EAGAIN)) {
        nn_msg_term (&msg);
        self->state = NN_REQ_STATE_DELAYED;
        return;
    }

    /*  Request was successfully sent. Set up the re-send timer
        in case the request gets lost somewhere further out
        in the topology. */
    if (nn_fast (rc == 0)) {
        nn_timer_start (&self->timer, self->resend_ivl);
        self->state = NN_REQ_STATE_ACTIVE;
        return;
    }

    /*  Unexpected error. */
    errnum_assert (0, -rc);
}
Example #18
0
static int nn_stcp_send (struct nn_pipebase *self, struct nn_msg *msg)
{
    struct nn_stcp *stcp;
    struct nn_iovec iov [3];

    stcp = nn_cont (self, struct nn_stcp, pipebase);
    nn_assert (stcp);

    nn_assert_state (stcp, NN_STCP_STATE_ACTIVE);
    nn_assert (stcp->outstate == NN_STCP_OUTSTATE_IDLE);

    /*  Move the message to the local storage. */
    nn_msg_term (&stcp->outmsg);
    nn_msg_mv (&stcp->outmsg, msg);

    /*  Serialise the message header. */
    nn_putll (stcp->outhdr, nn_chunkref_size (&stcp->outmsg.sphdr) +
        nn_chunkref_size (&stcp->outmsg.body));

    /*  Start async sending. */
    iov [0].iov_base = stcp->outhdr;
    iov [0].iov_len = sizeof (stcp->outhdr);
    iov [1].iov_base = nn_chunkref_data (&stcp->outmsg.sphdr);
    iov [1].iov_len = nn_chunkref_size (&stcp->outmsg.sphdr);
    iov [2].iov_base = nn_chunkref_data (&stcp->outmsg.body);
    iov [2].iov_len = nn_chunkref_size (&stcp->outmsg.body);
    nn_usock_send (stcp->usock, iov, 3);

    stcp->outstate = NN_STCP_OUTSTATE_SENDING;

    return 0;
}
Example #19
0
static int nn_stream_send (struct nn_pipebase *self, struct nn_msg *msg)
{
    struct nn_stream *stream;
    struct nn_iobuf iov [3];

    stream = nn_cont (self, struct nn_stream, pipebase);

    /*  Mave the message to the local storage. */
    nn_msg_term (&stream->outmsg);
    nn_msg_mv (&stream->outmsg, msg);

    /*  Serialise the message header. */
    nn_putll (stream->outhdr, nn_chunkref_size (&stream->outmsg.hdr) +
        nn_chunkref_size (&stream->outmsg.body));

    /*  Start async sending. */
    iov [0].iov_base = stream->outhdr;
    iov [0].iov_len = sizeof (stream->outhdr);
    iov [1].iov_base = nn_chunkref_data (&stream->outmsg.hdr);
    iov [1].iov_len = nn_chunkref_size (&stream->outmsg.hdr);
    iov [2].iov_base = nn_chunkref_data (&stream->outmsg.body);
    iov [2].iov_len = nn_chunkref_size (&stream->outmsg.body);;
    nn_usock_send (stream->usock, iov, 3);

    return 0;
}
Example #20
0
static void nn_stream_received (const struct nn_cp_sink **self,
    struct nn_usock *usock)
{
    struct nn_stream *stream;
    uint64_t size;

    stream = nn_cont (self, struct nn_stream, sink);
    switch (stream->instate) {
    case NN_STREAM_INSTATE_HDR:
        size = nn_getll (stream->inhdr);
        nn_msg_term (&stream->inmsg);
        nn_msg_init (&stream->inmsg, (size_t) size);
        if (!size) {
            nn_pipebase_received (&stream->pipebase);
            break;
        }
        stream->instate = NN_STREAM_INSTATE_BODY;
        nn_usock_recv (stream->usock, nn_chunkref_data (&stream->inmsg.body),
            (size_t) size);
        break;
    case NN_STREAM_INSTATE_BODY:
        nn_pipebase_received (&stream->pipebase);
        break;
    default:
        nn_assert (0);
    }
}
Example #21
0
int nn_recv (int s, void *buf, size_t len, int flags)
{
    int rc;
    struct nn_msg msg;
    size_t sz;
    void *chunk;

    NN_BASIC_CHECKS;

    if (nn_slow (!buf && len)) {
        errno = EFAULT;
        return -1;
    }

    rc = nn_sock_recv (self.socks [s], &msg, flags);
    if (nn_slow (rc < 0)) {
        errno = -rc;
        return -1;
    }

    if (len == NN_MSG) {
        chunk = nn_chunkref_getchunk (&msg.body);
        *(void**) buf = chunk;
        sz = nn_chunk_size (chunk);
    }
    else {
        sz = nn_chunkref_size (&msg.body);
        memcpy (buf, nn_chunkref_data (&msg.body), len < sz ? len : sz);
    }
    nn_msg_term (&msg);

    return (int) sz;
}
Example #22
0
static int nn_respondent_send (struct nn_sockbase *self, struct nn_msg *msg)
{
    int rc;
    struct nn_respondent *respondent;

    respondent = nn_cont (self, struct nn_respondent, xrespondent.sockbase);

    /*  If there's no survey going on, report EFSM error. */
    if (nn_slow (!(respondent->flags & NN_RESPONDENT_INPROGRESS)))
        return -EFSM;

    /*  Tag the message with survey ID. */
    nn_assert (nn_chunkref_size (&msg->sphdr) == 0);
    nn_chunkref_term (&msg->sphdr);
    nn_chunkref_init (&msg->sphdr, 4);
    nn_putl (nn_chunkref_data (&msg->sphdr), respondent->surveyid);

    /*  Try to send the message. If it cannot be sent due to pushback, drop it
        silently. */
    rc = nn_xrespondent_send (&respondent->xrespondent.sockbase, msg);
    if (nn_slow (rc == -EAGAIN)) {
        nn_msg_term (msg);
        return -EAGAIN;
    }
    errnum_assert (rc == 0, -rc);

    /*  Remember that no survey is being processed. */
    respondent->flags &= ~NN_RESPONDENT_INPROGRESS;

    return 0;
}
Example #23
0
int nn_xrespondent_recv (struct nn_sockbase *self, struct nn_msg *msg)
{
    int rc;
    struct nn_xrespondent *xrespondent;

    xrespondent = nn_cont (self, struct nn_xrespondent, sockbase);

    /*  Get the survey. */
    rc = nn_excl_recv (&xrespondent->excl, msg);
    if (rc == -EAGAIN)
        return -EAGAIN;
    errnum_assert (rc >= 0, -rc);

    /*  Split the survey ID from the body, if needed. */
    if (!(rc & NN_PIPE_PARSED)) {
        if (nn_slow (nn_chunkref_size (&msg->body) < sizeof (uint32_t))) {
            nn_msg_term (msg);
            return -EAGAIN;
        }
        nn_chunkref_term (&msg->hdr);
        nn_chunkref_init (&msg->hdr, sizeof (uint32_t));
        memcpy (nn_chunkref_data (&msg->hdr), nn_chunkref_data (&msg->body),
            sizeof (uint32_t));
        nn_chunkref_trim (&msg->body, sizeof (uint32_t));
    }

    return 0;
}
Example #24
0
static void nn_stream_sent (const struct nn_cp_sink **self,
    struct nn_usock *usock)
{
    struct nn_stream *stream;

    stream = nn_cont (self, struct nn_stream, sink);
    nn_pipebase_sent (&stream->pipebase);
    nn_msg_term (&stream->outmsg);
    nn_msg_init (&stream->outmsg, 0);
}
Example #25
0
int nn_dist_send (struct nn_dist *self, struct nn_msg *msg,
    struct nn_pipe *exclude)
{
    int rc;
    struct nn_list_item *it;
    struct nn_dist_data *data;
    struct nn_msg copy;

    /*  TODO: We can optimise for the case when there's only one outbound
        pipe here. No message copying is needed in such case. */

    /*  In the specific case when there are no outbound pipes. There's nowhere
        to send the message to. Deallocate it. */
    if (nn_slow (self->count) == 0) {
        nn_msg_term (msg);
        return 0;
    }

    /*  Send the message to all the subscribers. */
    nn_msg_bulkcopy_start (msg, self->count);
    it = nn_list_begin (&self->pipes);
    while (it != nn_list_end (&self->pipes)) {
       data = nn_cont (it, struct nn_dist_data, item);
       nn_msg_bulkcopy_cp (&copy, msg);
       if (nn_fast (data->pipe == exclude)) {
           nn_msg_term (&copy);
       }
       else {
           rc = nn_pipe_send (data->pipe, &copy);
           errnum_assert (rc >= 0, -rc);
           if (rc & NN_PIPE_RELEASE) {
               --self->count;
               it = nn_list_erase (&self->pipes, it);
               continue;
           }
       }
       it = nn_list_next (&self->pipes, it);
    }
    nn_msg_term (msg);

    return 0;
}
Example #26
0
void nn_sws_term (struct nn_sws *self)
{
    nn_assert_state (self, NN_SWS_STATE_IDLE);

    nn_fsm_event_term (&self->done);
    nn_msg_term (&self->outmsg);
    nn_msg_array_term (&self->inmsg_array);
    nn_pipebase_term (&self->pipebase);
    nn_wshdr_term (&self->wshdr);
    nn_fsm_term (&self->fsm);
}
Example #27
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;
}
Example #28
0
int nn_send (int s, const void *buf, size_t len, int flags)
{
    int rc;
    struct nn_msg msg;
    void *chunk;
    int nnmsg;

    NN_BASIC_CHECKS;

    if (nn_slow (!buf && len)) {
        errno = EFAULT;
        return -1;
    }

    /*  Create a message object. */
    if (len == NN_MSG) {
        chunk = *(void**) buf;
        if (nn_slow (chunk == NULL)) {
            errno = EFAULT;
            return -1;
        }
        len = nn_chunk_size (chunk);
        nn_msg_init_chunk (&msg, chunk);
        nnmsg = 1;
    }
    else {
        nn_msg_init (&msg, len);
        memcpy (nn_chunkref_data (&msg.body), buf, len);
        nnmsg = 0;
    }

    /*  Send it further down the stack. */
    rc = nn_sock_send (self.socks [s], &msg, flags);
    if (nn_slow (rc < 0)) {

        /*  If we are dealing with user-supplied buffer, detach it from
            the message object. */
        if (nnmsg)
            nn_chunkref_init (&msg.body, 0);

        nn_msg_term (&msg);
        errno = -rc;
        return -1;
    }
    nn_sock_stat_increment (self.socks [s], NN_STAT_MESSAGES_SENT, 1);
    nn_sock_stat_increment (self.socks [s], NN_STAT_BYTES_SENT, len);

    return (int) len;
}
Example #29
0
File: ctx.c Project: jjrdn/nanomsg
int nn_send (int s, const void *buf, size_t len, int flags)
{
    int rc;
    struct nn_msg msg;
    struct nn_chunk *ch;

    NN_BASIC_CHECKS;

#if defined NN_LATENCY_MONITOR
    nn_latmon_measure (NN_LATMON_SEND);
#endif

    if (nn_slow (!buf && len)) {
        errno = EFAULT;
        return -1;
    }

    /*  Create a message object. */
    if (len == NN_MSG) {
        ch = nn_chunk_from_data (*(void**) buf);
        if (nn_slow (ch == NULL)) {
            errno = EFAULT;
            return -1;
        }
        len = nn_chunk_size (ch);
        nn_msg_init_chunk (&msg, ch);
    }
    else {
        nn_msg_init (&msg, len);
        memcpy (nn_chunkref_data (&msg.body), buf, len);
    }

    /*  Send it further down the stack. */
    rc = nn_sock_send (self.socks [s], &msg, flags);
    if (nn_slow (rc < 0)) {
        nn_msg_term (&msg);
        errno = -rc;
        return -1;
    }

    return (int) len;
}
Example #30
0
static void nn_req_timeout (const struct nn_cp_sink **self,
    struct nn_timer *timer)
{
    int rc;
    struct nn_req *req;
    struct nn_msg msg;

    req = nn_cont (self, struct nn_req, sink);
    nn_assert (req->state == NN_REQ_STATE_SENT);

    /*  Re-send the request. If it cannot be sent, just drop it. */
    nn_msg_cp (&msg, &req->request);
    rc = nn_xreq_send (&req->xreq.sockbase, &msg);
    errnum_assert (rc == 0 || rc == -EAGAIN, -rc);
    if (nn_slow (rc == -EAGAIN))
        nn_msg_term (&msg);

    /*  Set up the next re-send timer. */
    nn_timer_start (&req->resend_timer, req->resend_ivl);
}