VirtualBox

Changeset 82865 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Jan 27, 2020 9:55:43 AM (5 years ago)
Author:
vboxsync
Message:

Devices/Serial: Reset the read/write pointers of the read buffers when the receive queue is flushed to prevent handing out stale data, ticketref:18671

File:
1 edited

Legend:

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

    r77324 r82865  
    9898
    9999/**
     100 * Resets the read buffer.
     101 *
     102 * @returns Number of bytes which were queued in the read buffer before reset.
     103 * @param   pThis               The host serial driver instance.
     104 */
     105DECLINLINE(size_t) drvHostSerialReadBufReset(PDRVHOSTSERIAL pThis)
     106{
     107    size_t cbOld = ASMAtomicXchgZ(&pThis->cbReadBuf, 0);
     108    ASMAtomicWriteU32(&pThis->offWrite,  0);
     109    ASMAtomicWriteU32(&pThis->offRead,   0);
     110
     111    return cbOld;
     112}
     113
     114
     115/**
    100116 * Returns number of bytes free in the read buffer and pointer to the start of the free space
    101117 * in the read buffer.
     
    370386    if (fQueueRecv)
    371387    {
    372         size_t cbOld = ASMAtomicXchgZ(&pThis->cbReadBuf, 0);
     388        size_t cbOld = drvHostSerialReadBufReset(pThis);
    373389        if (cbOld) /* Kick the I/O thread to fetch new data. */
    374390            rc = RTSerialPortEvtPollInterrupt(pThis->hSerialPort);
     
    468484                size_t cbRead = 0;
    469485                rc = RTSerialPortReadNB(pThis->hSerialPort, pvDst, cbToRead, &cbRead);
    470                 if (RT_SUCCESS(rc))
     486                /*
     487                 * No data being available while the port is marked as readable can happen
     488                 * if another thread changed the settings of the port inbetween the poll and
     489                 * the read call because it can flush all the buffered data (seen on Windows).
     490                 */
     491                if (rc != VINF_TRY_AGAIN)
    471492                {
    472                     drvHostSerialReadBufWriteAdv(pThis, cbRead);
    473                     /* Notify the device/driver above. */
    474                     rc = pThis->pDrvSerialPort->pfnDataAvailRdrNotify(pThis->pDrvSerialPort, cbRead);
    475                     AssertRC(rc);
     493                    if (RT_SUCCESS(rc))
     494                    {
     495                        drvHostSerialReadBufWriteAdv(pThis, cbRead);
     496                        /* Notify the device/driver above. */
     497                        rc = pThis->pDrvSerialPort->pfnDataAvailRdrNotify(pThis->pDrvSerialPort, cbRead);
     498                        AssertRC(rc);
     499                    }
     500                    else
     501                        LogRelMax(10, ("HostSerial#%d: Reading data failed even though the serial port is marked as readable (rc=%Rrc)\n",
     502                                       pThis->pDrvIns->iInstance, rc));
    476503                }
    477                 else
    478                     LogRelMax(10, ("HostSerial#%d: Reading data failed even though the serial port is marked as readable (rc=%Rrc)\n",
    479                                    pThis->pDrvIns->iInstance, rc));
    480504            }
    481505
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