VirtualBox

Changeset 41178 in vbox


Ignore:
Timestamp:
May 6, 2012 5:11:18 AM (13 years ago)
Author:
vboxsync
Message:

NAT: attempt to fix xTracker/#6188.

Location:
trunk/src/VBox/Devices/Network/slirp
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Network/slirp/slirp.c

    r40837 r41178  
    267267    0x0, 0x0, 0x0, 0x0, 0x0, 0x0
    268268};
     269
     270/**
     271 * This helper routine do the checks in descriptions to
     272 * ''fUnderPolling'' and ''fShouldBeRemoved'' flags
     273 * @returns 1 if socket removed and 0 if no changes was made.
     274 */
     275static int slirpVerifyAndFreeSocket(PNATState pData, struct socket *pSocket)
     276{
     277    AssertPtrReturn(pData, 0);
     278    AssertPtrReturn(pSocket, 0);
     279    AssertReturn(pSocket->fUnderPolling, 0);
     280    if (pSocket->fShouldBeRemoved)
     281    {
     282        pSocket->fUnderPolling = 0;
     283        sofree(pData, pSocket);
     284        /* so is PHANTOM, now */
     285        return 1;
     286    }
     287    return 0;
     288}
    269289
    270290#ifdef RT_OS_WINDOWS
     
    12381258            CONTINUE(tcp);
    12391259
     1260        Assert(!so->fUnderPolling);
     1261        so->fUnderPolling = 1;
    12401262        POLL_TCP_EVENTS(rc, error, so, &NetworkEvents);
    12411263
     
    12661288        {
    12671289            sorecvoob(pData, so);
     1290            if (slirpVerifyAndFreeSocket(pData, so))
     1291                CONTINUE(tcp);
    12681292        }
    12691293
     
    12821306                bool fRet = slirpConnectOrWrite(pData, so, true);
    12831307                LogFunc(("fRet:%RTbool\n", fRet));
     1308                if (slirpVerifyAndFreeSocket(pData, so))
     1309                    CONTINUE(tcp);
    12841310            }
    12851311#endif
     
    12901316            {
    12911317                TCP_CONNECT(pData, so);
     1318                if (slirpVerifyAndFreeSocket(pData, so))
     1319                    CONTINUE(tcp);
    12921320                if (!CHECK_FD_SET(so, NetworkEvents, closefds))
     1321                {
     1322                    so->fUnderPolling = 0;
    12931323                    CONTINUE(tcp);
     1324                }
    12941325            }
    12951326
    12961327            ret = soread(pData, so);
     1328            if (slirpVerifyAndFreeSocket(pData, so))
     1329                CONTINUE(tcp);
    12971330            /* Output it if we read something */
    12981331            if (RT_LIKELY(ret > 0))
    12991332                TCP_OUTPUT(pData, sototcpcb(so));
     1333
     1334            if (slirpVerifyAndFreeSocket(pData, so))
     1335                CONTINUE(tcp);
    13001336        }
    13011337
     
    13071343            || (so->so_close == 1))
    13081344        {
    1309             struct socket *pPrevSo = NULL;
    1310             /**
    1311              * we need easy way to detection mechanism if socket has been freed or not
    1312              * before continuing any further diagnostic.
    1313              */
    1314             pPrevSo = so->so_prev;
    1315             AssertPtr(pPrevSo);
    13161345            /*
    13171346             * drain the socket
    13181347             */
    1319             for (; pPrevSo->so_next == so ;)
     1348            for (;   so_next->so_prev == so
     1349                  && !slirpVerifyAndFreeSocket(pData, so);)
    13201350            {
    13211351                ret = soread(pData, so);
     1352                if (slirpVerifyAndFreeSocket(pData, so))
     1353                    break;
     1354
    13221355                if (ret > 0)
    13231356                    TCP_OUTPUT(pData, sototcpcb(so));
    1324                 else if (pPrevSo->so_next == so)
     1357                else if (so_next->so_prev == so)
    13251358                {
    13261359                    Log2(("%R[natsock] errno %d (%s)\n", so, errno, strerror(errno)));
     
    13281361                }
    13291362            }
    1330             if (pPrevSo->so_next == so)
     1363
     1364            /* if socket freed ''so'' is PHANTOM and next socket isn't points on it */
     1365            if (so_next->so_prev == so)
    13311366            {
    13321367                /* mark the socket for termination _after_ it was drained */
     
    13391374#endif
    13401375            }
     1376            if (so_next->so_prev == so)
     1377                so->fUnderPolling = 0;
    13411378            CONTINUE(tcp);
    13421379        }
     
    13521389        {
    13531390            if(!slirpConnectOrWrite(pData, so, false))
     1391            {
     1392                if (!slirpVerifyAndFreeSocket(pData, so))
     1393                    so->fUnderPolling = 0;
    13541394                CONTINUE(tcp);
     1395            }
    13551396        }
    13561397
     
    14031444        } /* SS_ISFCONNECTING */
    14041445#endif
     1446        if (!slirpVerifyAndFreeSocket(pData, so))
     1447            so->fUnderPolling = 0;
    14051448        LOOP_LABEL(tcp, so, so_next);
    14061449    }
  • trunk/src/VBox/Devices/Network/slirp/socket.c

    r40622 r41178  
    195195        m_freem(pData, so->so_m);
    196196#ifndef VBOX_WITH_SLIRP_MT
    197     if (so->so_next && so->so_prev)
    198     {
    199         remque(pData, so);  /* crashes if so is not in a queue */
    200         NSOCK_DEC();
    201     }
    202 
    203     RTMemFree(so);
     197    /*
     198     * We should not remove socket when polling routine do the polling
     199     * instead we mark it for deletion.
     200     */
     201    if (!so->fUnderPolling)
     202    {
     203        if (so->so_next && so->so_prev)
     204        {
     205            remque(pData, so);  /* crashes if so is not in a queue */
     206            NSOCK_DEC();
     207        }
     208
     209        RTMemFree(so);
     210    }
     211    else
     212        so->fShouldBeRemoved = 1;
    204213#else
    205214    so->so_deleted = 1;
  • trunk/src/VBox/Devices/Network/slirp/socket.h

    r40621 r41178  
    112112    int so_cCloneCounter;      /* number of clones */
    113113#endif
     114    /** These flags (''fUnderPolling'' and ''fShouldBeRemoved'') introduced to
     115     *  to let polling routine gain control over freeing socket whatever level of
     116     *  TCP/IP initiated socket releasing.
     117     *  So polling routine when start processing socket alter it's state to
     118     *  ''fUnderPolling'' to 1, and clean (set to 0) when it finish.
     119     *  When polling routine calls functions it should be ensure on return,
     120     *  whether ''fShouldBeRemoved'' set or not, and depending on state call
     121     *  ''sofree'' or continue socket processing.
     122     *  On ''fShouldBeRemoved'' equal to 1, polling routine should call ''sofree'',
     123     *  clearing ''fUnderPolling'' to do real freeng of the socket and removing from
     124     *  the queue.
     125     *  @todo: perhaps, to simplefy the things we need some helper function.
     126     *  @note: it's used like a bool, I use 'int' to avoid compiler warnings
     127     *  appearing if [-Wc++-compat] used.
     128     */
     129    int fUnderPolling;
     130    /** This flag used by ''sofree'' function in following manner
     131     *
     132     *  fUnderPolling = 1, then we don't remove socket from the queue, just
     133     *  alter value ''fShouldBeRemoved'' to 1, else we do removal.
     134     */
     135    int fShouldBeRemoved;
    114136};
    115137
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