VirtualBox

Changeset 70483 in vbox for trunk/src/VBox/Runtime


Ignore:
Timestamp:
Jan 7, 2018 9:43:45 PM (7 years ago)
Author:
vboxsync
Message:

IPRT/socket,poll: Try fix windows polling bug (not fallback) concerning sockets entered more than once into a poll set. The second handle wouldn't get events.

Location:
trunk/src/VBox/Runtime
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r3/socket.cpp

    r70481 r70483  
    163163     * This is ZERO if we're currently not subscribing to anything. */
    164164    uint32_t            fSubscribedEvts;
    165     /** Saved events which are only posted once. */
     165    /** Saved events which are only posted once and events harvested for
     166     * sockets entetered multiple times into to a poll set. */
    166167    uint32_t            fEventsSaved;
     168    /** Set if fEventsSaved contains harvested events. */
     169    bool                fHavestedEvents;
    167170    /** Set if we're using the polling fallback. */
    168171    bool                fPollFallback;
     
    505508    pThis->fSubscribedEvts          = 0;
    506509    pThis->fEventsSaved             = 0;
     510    pThis->fHavestedEvents          = false;
    507511    pThis->fPollFallback            = g_uWinSockInitedVersion < MAKEWORD(2, 0)
    508512                                   || g_pfnWSACreateEvent == NULL
     
    686690     */
    687691    int aSockets[2] = { -1, -1 };
    688     int (socketpair(AF_INET, SOCK_STREAM, IPPROTO_TCP, aSockets) == 0)
     692    if (socketpair(AF_INET, SOCK_STREAM, IPPROTO_TCP, aSockets) == 0)
    689693    {
    690694        *phServer = aSockets[0];
     
    28212825        if (g_pfnWSAEnumNetworkEvents(pThis->hNative, pThis->hEvent, &NetEvts) == 0)
    28222826        {
    2823             if (    (NetEvts.lNetworkEvents & FD_READ)
    2824                 &&  (fEvents & RTPOLL_EVT_READ)
    2825                 &&  NetEvts.iErrorCode[FD_READ_BIT] == 0)
     2827            if (   (NetEvts.lNetworkEvents & FD_READ)
     2828                && NetEvts.iErrorCode[FD_READ_BIT] == 0)
    28262829                fRetEvents |= RTPOLL_EVT_READ;
    28272830
    2828             if (    (NetEvts.lNetworkEvents & FD_WRITE)
    2829                 &&  (fEvents & RTPOLL_EVT_WRITE)
    2830                 &&  NetEvts.iErrorCode[FD_WRITE_BIT] == 0)
     2831            if (   (NetEvts.lNetworkEvents & FD_WRITE)
     2832                && NetEvts.iErrorCode[FD_WRITE_BIT] == 0)
    28312833                fRetEvents |= RTPOLL_EVT_WRITE;
    28322834
    2833             if (fEvents & RTPOLL_EVT_ERROR)
    2834             {
    2835                 if (NetEvts.lNetworkEvents & FD_CLOSE)
    2836                     fRetEvents |= RTPOLL_EVT_ERROR;
    2837                 else
    2838                     for (uint32_t i = 0; i < FD_MAX_EVENTS; i++)
    2839                         if (    (NetEvts.lNetworkEvents & (1L << i))
    2840                             &&  NetEvts.iErrorCode[i] != 0)
    2841                             fRetEvents |= RTPOLL_EVT_ERROR;
    2842             }
     2835            if (NetEvts.lNetworkEvents & FD_CLOSE)
     2836                fRetEvents |= RTPOLL_EVT_ERROR;
     2837            else
     2838                for (uint32_t i = 0; i < FD_MAX_EVENTS; i++)
     2839                    if (   (NetEvts.lNetworkEvents & (1L << i))
     2840                        && NetEvts.iErrorCode[i] != 0)
     2841                        fRetEvents |= RTPOLL_EVT_ERROR;
     2842
     2843            pThis->fEventsSaved = fRetEvents |= pThis->fEventsSaved;
    28432844        }
    28442845        else
     
    30353036     * Harvest events and clear the event mask for the next round of polling.
    30363037     */
    3037     uint32_t fRetEvents = rtSocketPollCheck(pThis, fEvents);
     3038    uint32_t fRetEvents;
    30383039# ifdef RT_OS_WINDOWS
    3039     pThis->fPollEvts = 0;
    3040 
    3041     /*
    3042      * Save the write event if required.
    3043      * It is only posted once and might get lost if the another source in the
    3044      * pollset with a higher priority has pending events.
    3045      */
    3046     if (   !fHarvestEvents
    3047         && fRetEvents)
    3048     {
    3049         pThis->fEventsSaved = fRetEvents;
    3050         fRetEvents = 0;
    3051     }
     3040    if (!pThis->fPollFallback)
     3041    {
     3042        if (!pThis->fHavestedEvents)
     3043        {
     3044            fRetEvents = rtSocketPollCheck(pThis, fEvents);
     3045            pThis->fHavestedEvents = true;
     3046        }
     3047        else
     3048            fRetEvents = pThis->fEventsSaved;
     3049        if (fHarvestEvents)
     3050            fRetEvents &= fEvents;
     3051        else
     3052            fRetEvents = 0;
     3053        pThis->fPollEvts = 0;
     3054    }
     3055    else
    30523056# endif
    3053 
    3054     /* Make the socket blocking again and unlock the handle. */
     3057    {
     3058        if (fHarvestEvents)
     3059            fRetEvents = rtSocketPollCheck(pThis, fEvents);
     3060        else
     3061            fRetEvents = 0;
     3062    }
     3063
     3064    /*
     3065     * Make the socket blocking again and unlock the handle.
     3066     */
    30553067    if (pThis->cUsers == 1)
    30563068    {
    30573069# ifdef RT_OS_WINDOWS
     3070        pThis->fEventsSaved   &= RTPOLL_EVT_ERROR;
     3071        pThis->fHavestedEvents = false;
    30583072        rtSocketPollClearEventAndRestoreBlocking(pThis);
    30593073# endif
  • trunk/src/VBox/Runtime/testcase/tstRTPoll.cpp

    r70481 r70483  
    194194        RTTESTI_CHECK(cbRead == sizeof(g_szHello) - 1 && memcmp(achBuf, g_szHello, sizeof(g_szHello) - 1) == 0);
    195195
    196 //        RTTESTI_CHECK_RC(RTPoll(hSet, 0, NULL,  NULL), VERR_TIMEOUT);
    197 //        RTTESTI_CHECK_RC(RTPoll(hSet, 1, NULL,  NULL), VERR_TIMEOUT);
     196        RTTESTI_CHECK_RC(RTPoll(hSet, 0, NULL,  NULL), VERR_TIMEOUT);
     197        RTTESTI_CHECK_RC(RTPoll(hSet, 1, NULL,  NULL), VERR_TIMEOUT);
    198198    }
    199199
     
    229229
    230230    RTTESTI_CHECK_RC(RTPollSetDestroy(hSet), VINF_SUCCESS);
    231 RTLogFlush(NULL);
    232231}
    233232
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