VirtualBox

Changeset 68717 in vbox for trunk


Ignore:
Timestamp:
Sep 11, 2017 3:55:43 PM (7 years ago)
Author:
vboxsync
Message:

Serial/DrvTCP: Fix for Windows hosts where the write event in a poll is only returned once initially and only after a send operation would return WSAEWOULDBLOCK

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Serial/DrvTCP.cpp

    r68699 r68717  
    8181    /** Flag whether the socket is in the pollset. */
    8282    bool                fTcpSockInPollSet;
     83    /** Flag whether the send buffer is full nad it is required to wait for more
     84     * space until there is room again. */
     85    bool                fXmitBufFull;
    8386
    8487    /** Thread for listening for new connections. */
     
    121124                                    fEvts, DRVTCP_POLLSET_ID_SOCKET);
    122125            if (RT_SUCCESS(rc))
     126            {
    123127                pThis->fTcpSockInPollSet = true;
     128                pThis->fXmitBufFull = false;
     129            }
    124130        }
    125131        else
    126132        {
     133            /*
     134             * Just return if the send buffer wasn't full till now and
     135             * the caller wants to check whether writing is possible with
     136             * the event set.
     137             *
     138             * On Windows the write event is only posted after a send operation returned
     139             * WSAEWOULDBLOCK. So without this we would block in the poll call below waiting
     140             * for an event which would never happen if the buffer has space left.
     141             */
     142            if (   (fEvts & RTPOLL_EVT_WRITE)
     143                && !pThis->fXmitBufFull)
     144            {
     145                *pfEvts = RTPOLL_EVT_WRITE;
     146                return VINF_SUCCESS;
     147            }
     148
    127149            /* Always include error event. */
    128150            fEvts |= RTPOLL_EVT_ERROR;
     
    183205                    else
    184206                    {
     207                        if (fEvtsRecv & RTPOLL_EVT_WRITE)
     208                            pThis->fXmitBufFull = false;
    185209                        *pfEvts = fEvtsRecv;
    186210                        break;
     
    258282        size_t cbBuf = *pcbWrite;
    259283        rc = RTSocketWriteNB(pThis->hTcpSock, pvBuf, cbBuf, pcbWrite);
     284        if (rc == VINF_TRY_AGAIN)
     285        {
     286            Assert(*pcbWrite == 0);
     287            pThis->fXmitBufFull = true;
     288            rc = VERR_TIMEOUT;
     289        }
    260290    }
    261291    else
    262292        *pcbWrite = 0;
    263293
    264     LogFlow(("%s: returns %Rrc\n", __FUNCTION__, rc));
     294    LogFlow(("%s: returns %Rrc *pcbWrite=%zu\n", __FUNCTION__, rc, *pcbWrite));
    265295    return rc;
    266296}
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette