Esempio n. 1
0
static uint32_t
socket_recv(socket_handle_t * p_socket_handle,
            void * p_buf,
            uint32_t buf_size,
            uint32_t * buf_len,
            int flags)
{
    if ((p_socket_handle->flags & O_NONBLOCK) != 0 &&
        (flags & MSG_WAITALL) == 0)
    {
        flags |= MSG_DONTWAIT;
    }
    uint32_t err_code = NRF_SUCCESS;
    if (mbuf_empty(&p_socket_handle->mbuf_head) == true)
    {
        if ((flags & MSG_DONTWAIT) != 0)
        {
            err_code = SOCKET_WOULD_BLOCK;
        }
        else
        {
            while ((mbuf_empty(&p_socket_handle->mbuf_head) == true) && (err_code == NRF_SUCCESS))
            {
                err_code = sd_app_evt_wait();
            }
        }
    }

    if (err_code == NRF_SUCCESS)
    {
        *buf_len = mbuf_read(&p_socket_handle->mbuf_head, p_buf, buf_size);
        p_socket_handle->read_events = 0;
    }
    return err_code;
}
Esempio n. 2
0
uint32_t mbuf_read(mbuf_t * p_mbuf, void * p_buf, uint32_t buf_size)
{
    uint32_t nbytes = 0;
    while (nbytes < buf_size && mbuf_empty(p_mbuf) == false)
    {
        mbuf_load(p_mbuf);
        void * p_current = p_mbuf->p_current;
        const uint32_t copy_len = p_mbuf->read(p_current,
                                               p_mbuf->read_pos,
                                               ((uint8_t *)p_buf) + nbytes,
                                               buf_size - nbytes);
        p_mbuf->read_pos += copy_len;
        nbytes += copy_len;
        if (mbuf_empty_current(p_mbuf) == true)
        {
            p_mbuf->free(p_mbuf->p_current);
            p_mbuf->p_current = NULL;
            p_mbuf->read_pos = 0;
        }
    }
    return nbytes;
}
Esempio n. 3
0
static rstatus_t
conn_send_queue(struct conn *conn)
{
    struct mbuf *mbuf, *nbuf;                   /* current and next mbuf */
    size_t mlen;                                /* current mbuf data length */
    ssize_t n;

    for (mbuf = STAILQ_FIRST(&conn->send_queue); mbuf != NULL; mbuf = nbuf) {
        nbuf = STAILQ_NEXT(mbuf, next);

        if (mbuf_empty(mbuf)) {
            continue;
        }

        mlen = mbuf_length(mbuf);
        n = conn_send_buf(conn, mbuf->pos, mlen);

        if (n < 0) {
            if (n == NC_EAGAIN) {
                return NC_OK;
            }
            return NC_ERROR;
        }

        mbuf->pos += n;
        if (n < mlen) {
            ASSERT(mbuf->pos < mbuf->end);
            return NC_OK;
        }

        ASSERT(mbuf->pos == mbuf->last);

        mbuf_remove(&conn->send_queue, mbuf);
        mbuf_put(mbuf);
    }

    conn->send_ready = 0;
    return NC_OK;
}
Esempio n. 4
0
/*
 * Pre-split copy handler invoked when the request is a multi vector -
 * 'get' or 'gets' request and is about to be split into two requests
 */
void
memcache_pre_splitcopy(struct mbuf *mbuf, void *arg)
{
    struct msg *r = arg;                  /* request vector */
    struct string get = string("get ");   /* 'get ' string */
    struct string gets = string("gets "); /* 'gets ' string */

    ASSERT(r->request);
    ASSERT(mbuf_empty(mbuf));

    switch (r->type) {
    case MSG_REQ_GET:
        mbuf_copy(mbuf, get.data, get.len);
        break;

    case MSG_REQ_GETS:
        mbuf_copy(mbuf, gets.data, gets.len);
        break;

    default:
        NOT_REACHED();
    }
}
Esempio n. 5
0
/*
 * copy one response from src to dst
 * return bytes copied
 * */
static rstatus_t
memcache_copy_bulk(struct msg *dst, struct msg *src)
{
    struct mbuf *mbuf, *nbuf;
    uint8_t *p;
    uint32_t len = 0;
    uint32_t bytes = 0;
    uint32_t i = 0;

    for (mbuf = STAILQ_FIRST(&src->mhdr);
         mbuf && mbuf_empty(mbuf);
         mbuf = STAILQ_FIRST(&src->mhdr)) {

        mbuf_remove(&src->mhdr, mbuf);
        mbuf_put(mbuf);
    }

    mbuf = STAILQ_FIRST(&src->mhdr);
    if (mbuf == NULL) {
        return NC_OK;           /* key not exists */
    }
    p = mbuf->pos;

    /* get : VALUE key 0 len\r\nval\r\n */
    /* gets: VALUE key 0 len cas\r\nval\r\n */

    ASSERT(*p == 'V');
    for (i = 0; i < 3; i++) {                 /*  eat 'VALUE key 0 '  */
        for (; *p != ' ';) {
            p++;
        }
        p++;
    }

    len = 0;
    for (; p < mbuf->last && isdigit(*p); p++) {
        len = len * 10 + (uint32_t)(*p - '0');
    }

    for (; p < mbuf->last && ('\r' != *p); p++) { /* eat cas for gets */
        ;
    }

    len += CRLF_LEN * 2;
    len += (p - mbuf->pos);

    bytes = len;

    /* copy len bytes to dst */
    for (; mbuf;) {
        if (mbuf_length(mbuf) <= len) {   /* steal this mbuf from src to dst */
            nbuf = STAILQ_NEXT(mbuf, next);
            mbuf_remove(&src->mhdr, mbuf);
            mbuf_insert(&dst->mhdr, mbuf);
            len -= mbuf_length(mbuf);
            mbuf = nbuf;
        } else {                        /* split it */
            nbuf = mbuf_get();
            if (nbuf == NULL) {
                return NC_ENOMEM;
            }
            mbuf_copy(nbuf, mbuf->pos, len);
            mbuf_insert(&dst->mhdr, nbuf);
            mbuf->pos += len;
            break;
        }
    }

    dst->mlen += bytes;
    src->mlen -= bytes;
    log_debug(LOG_VVERB, "memcache_copy_bulk copy bytes: %d", bytes);
    return NC_OK;
}