[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH v3 2/3] QIOChannelSocket: Implement io_async_write & io_async
From: |
Peter Xu |
Subject: |
Re: [PATCH v3 2/3] QIOChannelSocket: Implement io_async_write & io_async_flush |
Date: |
Tue, 28 Sep 2021 18:45:24 -0400 |
On Wed, Sep 22, 2021 at 07:24:22PM -0300, Leonardo Bras wrote:
> +static void qio_channel_socket_async_flush(QIOChannel *ioc,
> + Error **errp)
> +{
> + QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);
> + struct msghdr msg = {};
> + struct pollfd pfd;
> + struct sock_extended_err *serr;
> + struct cmsghdr *cm;
> + char control[CMSG_SPACE(sizeof(int) * SOCKET_MAX_FDS)];
> + int ret;
> +
> + memset(control, 0, CMSG_SPACE(sizeof(int) * SOCKET_MAX_FDS));
> + msg.msg_control = control;
> + msg.msg_controllen = sizeof(control);
> +
> + while (sioc->async_sent < sioc->async_queued) {
> + ret = recvmsg(sioc->fd, &msg, MSG_ERRQUEUE);
> + if (ret < 0) {
> + if (errno == EAGAIN) {
> + /* Nothing on errqueue, wait */
> + pfd.fd = sioc->fd;
> + pfd.events = 0;
> + ret = poll(&pfd, 1, 250);
> + if (ret == 0) {
> + /*
> + * Timeout : After 250ms without receiving any zerocopy
> + * notification, consider all data as sent.
> + */
> + break;
After a timeout, we'll break the while loop and continue parsing an invalid
msg [1]. Is that what we want?
Also, I don't think we can return the flush() even if timed out - iiuc we
should keep polling until we have async_sent==async_queued. It depends on how
we define flush(): if it's "when this function returns all data is sent", then
we should keep polling, and afaict this is what we want here right now.
> + } else if (ret < 0 ||
> + (pfd.revents & (POLLERR | POLLHUP | POLLNVAL))) {
> + error_setg_errno(errp, errno,
> + "Poll error");
> + break;
> + } else {
> + continue;
> + }
> + }
> + if (errno == EINTR) {
> + continue;
> + }
> +
> + error_setg_errno(errp, errno,
> + "Unable to read errqueue");
> + break;
> + }
> +
> + cm = CMSG_FIRSTHDR(&msg);
[1]
> + if (cm->cmsg_level != SOL_IP &&
> + cm->cmsg_type != IP_RECVERR) {
> + error_setg_errno(errp, EPROTOTYPE,
> + "Wrong cmsg in errqueue");
> + break;
> + }
--
Peter Xu
- [PATCH v3 1/3] QIOChannel: Add io_async_writev & io_async_flush callbacks, (continued)
[PATCH v3 2/3] QIOChannelSocket: Implement io_async_write & io_async_flush, Leonardo Bras, 2021/09/22
Re: [PATCH v3 2/3] QIOChannelSocket: Implement io_async_write & io_async_flush,
Peter Xu <=
[PATCH v3 3/3] multifd: Send using asynchronous write on nocomp to send RAM pages., Leonardo Bras, 2021/09/22
Re: [PATCH v3 0/3] QIOChannel async_write & async_flush + MSG_ZEROCOPY + multifd, Peter Xu, 2021/09/28