VirtualBox

Changeset 17213 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Feb 27, 2009 4:29:55 PM (16 years ago)
Author:
vboxsync
Message:

VBoxNetFlt.c: Proposed fix for the other race destruction race.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFlt.c

    r17197 r17213  
    989989{
    990990    PINTNETTRUNKIFPORT pIfPort;
     991    PVBOXNETFLTINS pCur;
    991992    int rc;
    992993
     994    *ppInstance = NULL;
    993995    rc = RTSemFastMutexRequest(pGlobals->hFastMtx);
    994996    AssertRCReturn(rc, rc);
     
    997999     * Look for an existing instance in the list.
    9981000     *
    999      * If found that it's being destroyed, wait for it to go away.
    1000      * Return instances in other states ASSUMING that it has lost the
    1001      * connection.
    1002      */
    1003     *ppInstance = vboxNetFltFindInstanceLocked(pGlobals, pszName);
    1004     while (*ppInstance)
     1001     * There might be an existing one in the list if the driver was unbound
     1002     * while it was connected to an internal network. We're running into
     1003     * a destruction race that is a bit similar to the one in
     1004     * vboxNetFltFactoryCreateAndConnect, only the roles are reversed
     1005     * and we're not in a position to back down. Instead of backing down
     1006     * we'll delay a bit giving the other thread time to complete the
     1007     * destructor.
     1008     */
     1009    pCur = vboxNetFltFindInstanceLocked(pGlobals, pszName);
     1010    while (pCur)
    10051011    {
    1006         VBOXNETFTLINSSTATE enmState = vboxNetFltGetState(*ppInstance);
     1012#if 0
     1013        uint32_t cRefs = ASMAtomicIncU32(&pCur->cRefs);
     1014        if (cRefs > 1)
     1015        {
     1016            VBOXNETFTLINSSTATE enmState = vboxNetFltGetState(pCur);
     1017            switch (enmState)
     1018            {
     1019                case kVBoxNetFltInsState_Unconnected:
     1020                case kVBoxNetFltInsState_Connected:
     1021                case kVBoxNetFltInsState_Disconnecting:
     1022                    if (pCur->fDisconnectedFromHost)
     1023                    {
     1024                        /* Wait for it to exit the transitional disconnecting
     1025                           state. It might otherwise be running the risk of
     1026                           upsetting the OS specific code...  */
     1027                        /** @todo This reconnect stuff should be serialized correctly for static
     1028                         *        devices. Shouldn't it? In the dynamic case we're using the INTNET
     1029                         *        outbound thrunk lock, but that doesn't quite cut it here, or does
     1030                         *        it? We could either transition to initializing  or make a callback
     1031                         *        while owning the mutext here... */
     1032                        if (enmState == kVBoxNetFltInsState_Disconnecting)
     1033                        {
     1034                            do
     1035                            {
     1036                                RTSemFastMutexRelease(pGlobals->hFastMtx);
     1037                                RTThreadSleep(2); /* (2ms) */
     1038                                RTSemFastMutexRequest(pGlobals->hFastMtx);
     1039                                enmState = ;
     1040                            }
     1041                            while (enmState == kVBoxNetFltInsState_Disconnecting);
     1042                            AssertMsg(enmState == kVBoxNetFltInsState_Unconnected, ("%d\n", enmState));
     1043                            Assert(pCur->fDisconnectedFromHost);
     1044                        }
     1045
     1046                        RTSemFastMutexRelease(pGlobals->hFastMtx);
     1047                        *ppInstance = pCur;
     1048                        return VINF_ALREADY_INITIALIZED;
     1049                    }
     1050                    /* fall thru */
     1051
     1052                default:
     1053                {
     1054                    bool fDfH = pCur->fDisconnectedFromHost;
     1055                    RTSemFastMutexRelease(pGlobals->hFastMtx);
     1056                    vboxNetFltRelease(pCur, false /* fBusy */);
     1057                    LogRel(("VBoxNetFlt: Huh? An instance of '%s' already exists! [pCur=%p cRefs=%d fDfH=%RTbool enmState=%d]\n",
     1058                            pszName, pCur, cRefs - 1, fDfH, enmState));
     1059                    *ppInstance = NULL;
     1060                    return VERR_INTNET_FLT_IF_BUSY;
     1061                }
     1062            }
     1063        }
     1064
     1065        /* Zero references, it's being destroyed. Delay a bit so the destructor
     1066           can finish its work and try again. (vboxNetFltNewInstance will fail
     1067           with duplicate name if we don't.) */
     1068# ifdef RT_STRICT
     1069        Assert(cRefs == 1);
     1070        enmState = vboxNetFltGetState(pCur);
     1071        AssertMsg(   enmState == kVBoxNetFltInsState_Unconnected
     1072                  || enmState == kVBoxNetFltInsState_Disconnecting
     1073                  || enmState == kVBoxNetFltInsState_Destroyed, ("%d\n", enmState));
     1074# endif
     1075        ASMAtomicDecU32(&pCur->cRefs);
     1076        RTSemFastMutexRelease(pGlobals->hFastMtx);
     1077        RTThreadSleep(2); /* (2ms) */
     1078        rc = RTSemFastMutexRequest(pGlobals->hFastMtx);
     1079        AssertRCReturn(rc, rc);
     1080
     1081#else /* old code: */
     1082        VBOXNETFTLINSSTATE enmState = vboxNetFltGetState(pCur);
    10071083        if (    enmState != kVBoxNetFltInsState_Destroying
    10081084            &&  enmState != kVBoxNetFltInsState_Destroyed)
    10091085        {
    10101086            /** @todo r=bird: who is making sure this is a genuine reconnection case? */
    1011             vboxNetFltRetain(*ppInstance, false /* fBusy */);
     1087            vboxNetFltRetain(pCur, false /* fBusy */);
    10121088            RTSemFastMutexRelease(pGlobals->hFastMtx);
     1089            *ppInstance = pCur;
    10131090            return VINF_ALREADY_INITIALIZED;
    10141091        }
     
    10191096        rc = RTSemFastMutexRequest(pGlobals->hFastMtx);
    10201097        AssertRCReturn(rc, rc);
     1098#endif
    10211099
    10221100        /* try again */
    1023         *ppInstance = vboxNetFltFindInstanceLocked(pGlobals, pszName);
     1101        pCur = vboxNetFltFindInstanceLocked(pGlobals, pszName);
    10241102    }
    10251103
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