VirtualBox

Changeset 84688 in vbox


Ignore:
Timestamp:
Jun 5, 2020 9:04:51 AM (4 years ago)
Author:
vboxsync
Message:

Devices/Serial/DrvTCP: Avoid filling up the pipe with external woken up requests by setting a flag and avoiding writes to the pipe when it is already set, also drain the complete pipe in one go when checking for external requests instead of processing just a single item

File:
1 edited

Legend:

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

    r84157 r84688  
    9191    /** Flag to signal listening thread to shut down. */
    9292    bool volatile       fShutdown;
     93    /** Flag to signal whether the thread was woken up from external. */
     94    bool volatile       fWokenUp;
    9395} DRVTCP, *PDRVTCP;
    9496
     
    142144static int drvTcpWakeupPipeCheckForRequest(PDRVTCP pThis, uint32_t fEvts)
    143145{
    144     uint8_t bReason;
    145     size_t cbRead = 0;
    146     int rc = RTPipeRead(pThis->hPipeWakeR, &bReason, 1, &cbRead);
    147     if (rc == VINF_TRY_AGAIN) /* Nothing there so we are done here. */
    148         rc = VINF_SUCCESS;
    149     else if (RT_SUCCESS(rc))
    150     {
    151         if (bReason == DRVTCP_WAKEUP_REASON_EXTERNAL)
    152             rc = VERR_INTERRUPTED;
    153         else if (bReason == DRVTCP_WAKEUP_REASON_NEW_CONNECTION)
     146    int rc = VINF_SUCCESS;
     147
     148    while (   RT_SUCCESS(rc)
     149           || rc == VERR_INTERRUPTED)
     150    {
     151        uint8_t bReason;
     152        size_t cbRead = 0;
     153        int rc2 = RTPipeRead(pThis->hPipeWakeR, &bReason, 1, &cbRead);
     154        if (rc2 == VINF_TRY_AGAIN) /* Nothing there so we are done here. */
     155            break;
     156        else if (RT_SUCCESS(rc2))
    154157        {
    155             Assert(pThis->hTcpSock == NIL_RTSOCKET);
    156 
    157             /* Read the socket handle. */
    158             RTSOCKET hTcpSockNew = NIL_RTSOCKET;
    159             rc = RTPipeReadBlocking(pThis->hPipeWakeR, &hTcpSockNew, sizeof(hTcpSockNew), NULL);
    160             AssertRC(rc);
    161 
    162             /* Always include error event. */
    163             fEvts |= RTPOLL_EVT_ERROR;
    164             rc = RTPollSetAddSocket(pThis->hPollSet, hTcpSockNew,
    165                                     fEvts, DRVTCP_POLLSET_ID_SOCKET);
    166             if (RT_SUCCESS(rc))
    167                 pThis->hTcpSock = hTcpSockNew;
     158            if (bReason == DRVTCP_WAKEUP_REASON_EXTERNAL)
     159            {
     160                ASMAtomicXchgBool(&pThis->fWokenUp, false);
     161                rc = VERR_INTERRUPTED;
     162            }
     163            else if (bReason == DRVTCP_WAKEUP_REASON_NEW_CONNECTION)
     164            {
     165                Assert(pThis->hTcpSock == NIL_RTSOCKET);
     166
     167                /* Read the socket handle. */
     168                RTSOCKET hTcpSockNew = NIL_RTSOCKET;
     169                rc = RTPipeReadBlocking(pThis->hPipeWakeR, &hTcpSockNew, sizeof(hTcpSockNew), NULL);
     170                AssertRC(rc);
     171
     172                /* Always include error event. */
     173                fEvts |= RTPOLL_EVT_ERROR;
     174                rc = RTPollSetAddSocket(pThis->hPollSet, hTcpSockNew,
     175                                        fEvts, DRVTCP_POLLSET_ID_SOCKET);
     176                if (RT_SUCCESS(rc))
     177                    pThis->hTcpSock = hTcpSockNew;
     178            }
     179            else
     180                AssertMsgFailed(("Unknown wakeup reason in pipe %u\n", bReason));
    168181        }
    169         else
    170             AssertMsgFailed(("Unknown wakeup reason in pipe %u\n", bReason));
    171182    }
    172183
     
    289300static DECLCALLBACK(int) drvTcpPollInterrupt(PPDMISTREAM pInterface)
    290301{
     302    int rc = VINF_SUCCESS;
    291303    PDRVTCP pThis = RT_FROM_MEMBER(pInterface, DRVTCP, IStream);
    292     return drvTcpPollerKick(pThis, DRVTCP_WAKEUP_REASON_EXTERNAL);
     304
     305    if (!ASMAtomicXchgBool(&pThis->fWokenUp, true))
     306        rc = drvTcpPollerKick(pThis, DRVTCP_WAKEUP_REASON_EXTERNAL);
     307
     308    return rc;
    293309}
    294310
     
    555571    pThis->ListenThread                 = NIL_RTTHREAD;
    556572    pThis->fShutdown                    = false;
     573    pThis->fWokenUp                     = false;
    557574    /* IBase */
    558575    pDrvIns->IBase.pfnQueryInterface    = drvTCPQueryInterface;
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