VirtualBox

Changeset 63583 in vbox


Ignore:
Timestamp:
Aug 18, 2016 11:16:44 AM (8 years ago)
Author:
vboxsync
Message:

DrvHostSerial/Linux: fix pegging one CPU if TIOCMIWAIT fails constantly (ACM devices don't support TIOCM_DSR for example), switch to polling mode instead like we do on other hosts. ticketref:7796

File:
1 edited

Legend:

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

    r62956 r63583  
    114114    /** The write end of the control pipe */
    115115    RTPIPE                      hWakeupPipeW;
    116 # ifndef RT_OS_LINUX
    117116    /** The current line status.
    118117     * Used by the polling version of drvHostSerialMonitorThread.  */
    119118    int                         fStatusLines;
    120 # endif
    121119#elif defined(RT_OS_WINDOWS)
    122120    /** the device handle */
     
    895893{
    896894    PDRVHOSTSERIAL pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTSERIAL);
    897     int rc = VINF_SUCCESS;
    898895    unsigned long const uStatusLinesToCheck = TIOCM_CAR | TIOCM_RNG | TIOCM_DSR | TIOCM_CTS;
     896#ifdef RT_OS_LINUX
     897    bool fPoll = false;
     898#endif
    899899
    900900    if (pThread->enmState == PDMTHREADSTATE_INITIALIZING)
     
    908908         * Get the status line state.
    909909         */
    910         rc = ioctl(RTFileToNative(pThis->hDeviceFile), TIOCMGET, &statusLines);
    911         if (rc < 0)
     910        int rcPsx = ioctl(RTFileToNative(pThis->hDeviceFile), TIOCMGET, &statusLines);
     911        if (rcPsx < 0)
    912912        {
    913913            PDMDrvHlpVMSetRuntimeError(pDrvIns, 0 /*fFlags*/, "DrvHostSerialFail",
     
    940940         * modem irqs and so the monitor thread never gets released. The workaround
    941941         * is to send a signal after each tcsetattr.
     942         *
     943         * TIOCMIWAIT doesn't work for the DSR line with TIOCM_DSR set
     944         * (see http://lxr.linux.no/#linux+v4.7/drivers/usb/class/cdc-acm.c#L949)
     945         * However as it is possible to query the line state we will not just clear
     946         * the TIOCM_DSR bit from the lines to check but resort to the polling
     947         * approach just like on other hosts.
    942948         */
    943         ioctl(RTFileToNative(pThis->hDeviceFile), TIOCMIWAIT, uStatusLinesToCheck);
     949        if (!fPoll)
     950        {
     951            rcPsx = ioctl(RTFileToNative(pThis->hDeviceFile), TIOCMIWAIT, uStatusLinesToCheck);
     952            if (rcPsx < 0)
     953            {
     954                LogRel(("Serial#%u: Failed to wait for status line change, switch to polling\n", pDrvIns->iInstance));
     955                fPoll = true;
     956                pThis->fStatusLines = statusLines;
     957            }
     958        }
     959        else
     960        {
     961            /* Poll for status line change. */
     962            if (!((statusLines ^ pThis->fStatusLines) & uStatusLinesToCheck))
     963                PDMR3ThreadSleep(pThread, 500); /* 0.5 sec */
     964            pThis->fStatusLines = statusLines;
     965        }
    944966# else
    945967        /* Poll for status line change. */
     
    948970        pThis->fStatusLines = statusLines;
    949971# endif
    950     }
    951     while (PDMTHREADSTATE_RUNNING == pThread->enmState);
     972    } while (PDMTHREADSTATE_RUNNING == pThread->enmState);
    952973
    953974    return VINF_SUCCESS;
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