mtcp-stack / mtcp

mTCP: A Highly Scalable User-level TCP Stack for Multicore Systems
Other
1.98k stars 435 forks source link

mtcp use poll func set timeout #257

Open awzhgw opened 5 years ago

awzhgw commented 5 years ago

I am using mtcp as follows:

  1. When I write some buffer to the peer, I call the mtcp_write function, but I have to write it all. I used the poll to set the timeout. Now, after I switch mtcp, can the poll be used? this is my code:
static inline int32_t streamtowrite(int sock, const void *buff, uint32_t leng, uint32_t msecto)
{
    uint32_t sent = 0;
    int32_t i;
    struct pollfd pfd;
    double s, c;
    uint32_t msecpassed;

    s = 0.0;
    pfd.fd = sock;
    pfd.events = POLLOUT;
    pfd.revents = 0;
    while (1)
    {
        i = write(sock, ((uint8_t *)buff) + sent, leng - sent);
        if (i == 0)
        {
            return -errno;
        }
        if (i > 0)
        {
            sent += i;
        }
        else if (ERRNO_ERROR)
        {
            return -errno;
        }
        if (sent >= leng)
        {
            break;
        }
        if (s == 0.0)
        {
            s = monotonic_seconds();
            msecpassed = 0;
        }
        else
        {
            c = monotonic_seconds();
            msecpassed = (c - s) * 1000.0;
            if (msecpassed >= msecto)
            {
                return -errno;
            }
        }
        pfd.revents = 0;
        if (ff_poll(&pfd, 1, msecto - msecpassed) < 0)
        {
            if (errno != EINTR)
            {
                return -errno;
            }
            else
            {
                continue;
            }
        }
        if (pfd.revents & (POLLHUP | POLLERR))
        {
            return -errno;
        }
        if ((pfd.revents & POLLOUT) == 0)
        {
            errno = ETIMEDOUT;
            return -errno;
        }
    }
    return sent;
}

how to change ? beacause mtcp cannot support poll func

eunyoung14 commented 5 years ago

mTCP supports epoll-like event system, mtcp_epoll_wait. Please use it instead.

awzhgw commented 5 years ago

@eunyoung14 ,, it can be write like this:

static inline int32_t streamtoread(int sock, void *buff, uint32_t leng, uint32_t msecto) { uint32_t rcvd = 0; int i; int cpu = sched_getcpu(); struct mtcp_epoll_event ev; double s, c; uint32_t msecpassed;

s = 0.0;
ev.data.sockid = sock;
ev.events = MTCP_EPOLLIN;

while (1)
{
    i = mtcp_read(g_mctx[cpu],sock, ((uint8_t *)buff) + rcvd, leng - rcvd);
    if (i == 0)
    {
        errno = ECONNRESET;
        return -errno;
    }
    if (i > 0)
    {
        rcvd += i;
    }
    else if (ERRNO_ERROR)
    {
        return -errno;
    }
    if (ev.events & MTCP_EPOLLHUP)
    {
        return rcvd;
    }
    if (rcvd >= leng)
    {
        break;
    }
    if (s == 0.0)
    {
        s = monotonic_seconds();
        msecpassed = 0;
    }
    else
    {
        c = monotonic_seconds();
        msecpassed = (c - s) * 1000.0;
        if (msecpassed >= msecto)
        {
            errno = ETIMEDOUT;
            return -errno;
        }
    }
    ev.events = 0;
    if (mtcp_epool_wait(g_mctx[cpu],&ev, 1, msecto - msecpassed) < 0)
    {
        if (errno != EINTR)
        {
            return -errno;
        }
        else
        {
            continue;
        }
    }
    if (ev.events & MTCP_EPOLLERR)
    {
        return -errno;
    }
    if ((ev.events & MTCP_EPOLLIN) == 0)
    {
        errno = ETIMEDOUT;
        return -errno;
    }
}
return rcvd;

} No need to call mtcp_epoll_create or mtcp_epoll_ctl func?

???