Пример #1
0
static rstatus_t
conn_recv_queue(struct conn *conn)
{
    struct mbuf *mbuf;
    size_t msize;         /* current mbuf size */
    ssize_t n;

    mbuf = STAILQ_LAST(&conn->recv_queue, mbuf, next);
    if (mbuf == NULL || mbuf_full(mbuf)) {
        mbuf = mbuf_get();
        if (mbuf == NULL) {
            return NC_ENOMEM;
        }
        mbuf_insert(&conn->recv_queue, mbuf);
    }

    msize = mbuf_size(mbuf);
    ASSERT(msize > 0);

    n = conn_recv_buf(conn, mbuf->last, msize);
    if (n < 0) {
        if (n == NC_EAGAIN) {
            return NC_OK;
        }
        return NC_ERROR;
    }

    ASSERT((mbuf->last + n) <= mbuf->end);
    mbuf->last += n;
    return NC_OK;
}
Пример #2
0
struct mbuf *mbuf_queue_get(struct context *ctx, struct mhdr *q)
{
    struct mbuf *buf = NULL;

    if (!STAILQ_EMPTY(q)) buf = STAILQ_LAST(q, mbuf, next);

    if (buf == NULL || mbuf_full(buf)) {
        buf = mbuf_get(ctx);
        STAILQ_INSERT_TAIL(q, buf, next);
    }
    return buf;
}
Пример #3
0
/*
 * Copy n bytes from memory area pos to mbuf.
 *
 * The memory areas should not overlap and the mbuf should have
 * enough space for n bytes.
 */
void
mbuf_copy(struct mbuf *mbuf, uint8_t *pos, size_t n)
{
    if (n == 0) {
        return;
    }

    /* mbuf has space for n bytes */
    ASSERT(!mbuf_full(mbuf) && n <= mbuf_size(mbuf));

    /* no overlapping copy */
    ASSERT(pos < mbuf->start || pos >= mbuf->end);

    dn_memcpy(mbuf->last, pos, n);
    mbuf->last += n;
}
Пример #4
0
static void
direct_reply(struct context *ctx, struct conn *conn, struct msg *smsg, char *_msg) {
    struct mbuf *mbuf;
    int n;
    struct msg *msg = msg_get(conn, true, conn->redis);
    if (msg == NULL) {
        conn->err = errno;
        conn->done = 1;
        return;
    }

    mbuf = STAILQ_LAST(&msg->mhdr, mbuf, next);
    if (mbuf == NULL || mbuf_full(mbuf)) {
        mbuf = mbuf_get();
        if (mbuf != NULL) {
            mbuf_insert(&msg->mhdr, mbuf);
            msg->pos = mbuf->pos;
        }
    }
    if (mbuf == NULL) {
        conn->err = errno;
        conn->done = 1;
        msg_put(msg);
        return;
    }

    smsg->peer = msg;
    msg->peer = smsg;
    msg->request = 0;

    n = (int)strlen(_msg);
    memcpy(mbuf->last, _msg, (size_t)n);
    mbuf->last += n;
    msg->mlen += (uint32_t)n;
    smsg->done = 1;

    event_add_out(ctx->evb, conn);
    conn->enqueue_outq(ctx, conn, smsg);
}
Пример #5
0
/*
 * note: we should not call conn_add_out here.
 * because we may call append many times.
 */
rstatus_t
conn_sendq_append(struct conn *conn, char *pos, size_t n)
{
    struct mbuf *mbuf;
    size_t bytes = 0;
    size_t len;

    while (bytes < n) {
        mbuf = STAILQ_LAST(&conn->send_queue, mbuf, next);
        if ((mbuf == NULL) || mbuf_full(mbuf)) {
            mbuf = mbuf_get();
            if (mbuf == NULL) {
                return NC_ENOMEM;
            }
            mbuf_insert(&conn->send_queue, mbuf);
        }

        len = MIN(mbuf_size(mbuf), n - bytes);
        mbuf_copy(mbuf, (uint8_t *)pos + bytes, len);
        bytes += len;
    }

    return NC_OK;
}