VirtualBox

Changeset 10819

Show
Ignore:
Timestamp:
07/22/08 19:58:54 (2 months ago)
Author:
vboxsync
Message:

intnet: Use the IPRT handle table, validate against the session when looking up the handle, and do proper reference counting of the interfaces when resolving a handle. Fixed an issue in the interface destructure where anyone that could (very theorically) be sleeping on it wouldn't decrement the waiter count as we wanted them to.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/include/VBox/intnet.h

    r10806 r10819  
    828828 * @returns VBox status code. 
    829829 * @param   pIntNet     The instance data. 
    830  * @param   hIF         The interface handle. 
     830 * @param   hIf         The interface handle. 
     831 * @param   pSession        The caller's session. 
    831832 * @param   ppRing0Buf  Where to store the address of the ring-3 mapping. 
    832833 */ 
    833 INTNETR0DECL(int) INTNETR0IfGetRing0Buffer(PINTNET pIntNet, INTNETIFHANDLE hIf, PINTNETBUF *ppRing0Buf); 
     834INTNETR0DECL(int) INTNETR0IfGetRing0Buffer(PINTNET pIntNet, INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, PINTNETBUF *ppRing0Buf); 
    834835 
    835836/** 
     
    838839 * @returns VBox status code. 
    839840 * @param   pIntNet         The instance data. 
    840  * @param   hIF             The interface handle. 
     841 * @param   hIf             The interface handle. 
    841842 * @param   pSession        The caller's session. 
    842843 * @param   ppRing3Buf      Where to store the address of the ring-3 mapping. 
     
    865866 * @returns VBox status code. 
    866867 * @param   pIntNet     The instance data. 
    867  * @param   hIF         The interface handle. 
     868 * @param   hIf         The interface handle. 
    868869 * @param   pSession    The caller's session. 
    869870 * @param   pvFrame     Pointer to the frame. Optional, please don't use. 
  • trunk/src/VBox/Devices/Network/SrvIntNetR0.cpp

    r10806 r10819  
    3737#include <iprt/string.h> 
    3838#include <iprt/time.h> 
     39#include <iprt/handletable.h> 
    3940 
    4041 
     
    6162    /** Whether the interface is active or not. */ 
    6263    bool                    fActive; 
     64    /** Whether someone is currently in the destructor. */ 
     65    bool volatile           fDestroying; 
    6366    /** Number of yields done to try make the interface read pending data. 
    6467     * We will stop yeilding when this reaches a threshold assuming that the VM is paused or 
     
    7578    R3PTRTYPE(PINTNETBUF)   pIntBufDefaultR3; 
    7679    /** Event semaphore which a receiver thread will sleep on while waiting for data to arrive. */ 
    77     RTSEMEVENT              Event; 
     80    RTSEMEVENT volatile     Event; 
    7881    /** Number of threads sleeping on the Event semaphore. */ 
    7982    uint32_t                cSleepers; 
     
    8184     * When this is INTNET_HANDLE_INVALID a sleeper which is waking up 
    8285     * should return with the appropriate error condition. */ 
    83     INTNETIFHANDLE         hIf; 
     86    INTNETIFHANDLE volatile hIf; 
    8487    /** Pointer to the network this interface is connected to. 
    8588     * This is protected by the INTNET::FastMutex. */ 
     
    160163 
    161164/** 
    162  * Handle table entry. 
    163  * @todo move to IPRT. 
    164  */ 
    165 typedef union INTNETHTE 
    166 { 
    167     /** Pointer to the object we're a handle for. */ 
    168     PINTNETIF               pIF; 
    169     /** Index to the next free entry. */ 
    170     uintptr_t               iNext; 
    171 } INTNETHTE; 
    172 /** Pointer to a handle table entry. */ 
    173 typedef INTNETHTE *PINTNETHTE; 
    174  
    175  
    176 /** 
    177  * Handle table. 
    178  * @todo move to IPRT (RTHandleTableCreate/Destroy/Add/Delete/Lookup). 
    179  */ 
    180 typedef struct INTNETHT 
    181 { 
    182     /** Spinlock protecting all access. */ 
    183     RTSPINLOCK              Spinlock; 
    184     /** Pointer to the handle table. */ 
    185     PINTNETHTE              paEntries; 
    186     /** The number of allocated handles. */ 
    187     uint32_t                cAllocated; 
    188     /** The index of the first free handle entry. 
    189      * UINT32_MAX means empty list. */ 
    190     uint32_t volatile       iHead; 
    191     /** The index of the last free handle entry. 
    192      * UINT32_MAX means empty list. */ 
    193     uint32_t volatile       iTail; 
    194 } INTNETHT; 
    195 /** Pointer to a handle table. */ 
    196 typedef INTNETHT *PINTNETHT; 
    197  
    198  
    199 /** 
    200165 * Internal networking instance. 
    201166 */ 
     
    208173    PINTNETNETWORK volatile pNetworks; 
    209174    /** Handle table for the interfaces. */ 
    210     INTNETHT                IfHandles; 
     175    RTHANDLETABLE           hHtIfs; 
    211176} INTNET; 
    212177 
     
    223188 
    224189/** 
    225  * Validates and translates an interface handle to a interface pointer. 
    226  * 
    227  * The caller already owns the spinlock, which means this is 
    228  * for internal use only. 
    229  * 
    230  * @returns Pointer to interface. 
    231  * @returns NULL if the handle is invalid. 
    232  * @param   pHT         Pointer to the handle table. 
    233  * @param   hIF         The interface handle to validate and translate. 
    234  * 
    235  * @internal 
    236  */ 
    237 DECLINLINE(PINTNETIF) intnetR0Handle2IFPtrLocked(PINTNETHT pHT, INTNETIFHANDLE hIF) 
    238 
    239     if (RT_LIKELY((hIF & INTNET_HANDLE_MAGIC) == INTNET_HANDLE_MAGIC)) 
    240     { 
    241         const uint32_t i = hIF & INTNET_HANDLE_INDEX_MASK; 
    242         if (RT_LIKELY(   i < pHT->cAllocated 
    243                       && pHT->paEntries[i].iNext >= INTNET_HANDLE_MAX 
    244                       && pHT->paEntries[i].iNext != UINT32_MAX)) 
    245             return pHT->paEntries[i].pIF; 
    246     } 
    247     return NULL; 
    248 
    249  
    250  
    251 /** 
    252  * Validates and translates an interface handle to a interface pointer. 
    253  * 
    254  * @returns Pointer to interface. 
    255  * @returns NULL if the handle is invalid. 
    256  * @param   pHT         Pointer to the handle table. 
    257  * @param   hIF         The interface handle to validate and translate. 
    258  */ 
    259 DECLINLINE(PINTNETIF) intnetR0Handle2IFPtr(PINTNETHT pHT, INTNETIFHANDLE hIF) 
    260 
    261     AssertPtr(pHT); 
    262     RTSPINLOCKTMP   Tmp = RTSPINLOCKTMP_INITIALIZER; 
    263     RTSpinlockAcquire(pHT->Spinlock, &Tmp); 
    264     PINTNETIF pIF = intnetR0Handle2IFPtrLocked(pHT, hIF); 
    265     RTSpinlockRelease(pHT->Spinlock, &Tmp); 
    266  
    267     return pIF; 
    268 
    269  
    270  
    271 /** 
    272  * Allocates a handle for an interface. 
    273  * 
    274  * @returns Handle on success. 
    275  * @returns Invalid handle on failure. 
    276  * @param   pIntNet     Pointer to the instance data. 
    277  * @param   pIF         The interface which we're allocating a handle for. 
    278  */ 
    279 static INTNETIFHANDLE intnetR0HandleAllocate(PINTNET pIntNet, PINTNETIF pIF) 
    280 
    281     Assert(pIF); 
    282     Assert(pIntNet); 
    283     unsigned    cTries = 10; 
    284     PINTNETHT   pHT = &pIntNet->IfHandles; 
    285     PINTNETHTE  paNew = NULL; 
    286  
    287     RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; 
    288     RTSpinlockAcquire(pHT->Spinlock, &Tmp); 
    289     for (;;) 
    290     { 
    291         /* 
    292          * Check the free list. 
    293          */ 
    294         uint32_t i = pHT->iHead; 
    295         if (i != UINT32_MAX) 
    296         { 
    297             pHT->iHead = pHT->paEntries[i].iNext; 
    298             if (pHT->iHead == UINT32_MAX) 
    299                 pHT->iTail = UINT32_MAX; 
    300  
    301             pHT->paEntries[i].pIF = pIF; 
    302             RTSpinlockRelease(pHT->Spinlock, &Tmp); 
    303             if (paNew) 
    304                 RTMemFree(paNew); 
    305             return i | INTNET_HANDLE_MAGIC; 
    306         } 
    307  
    308         /* 
    309          * Leave the spinlock and allocate a new array. 
    310          */ 
    311         const unsigned cNew = pHT->cAllocated + 128; 
    312         RTSpinlockRelease(pHT->Spinlock, &Tmp); 
    313         if (--cTries <= 0) 
    314         { 
    315             AssertMsgFailed(("Giving up!\n")); 
    316             break; 
    317         } 
    318         paNew = (PINTNETHTE)RTMemAlloc(sizeof(*paNew) * cNew); 
    319         if (!paNew) 
    320             break; 
    321  
    322         /* 
    323          * Acquire the spinlock and check if someone raced us. 
    324          */ 
    325         RTSpinlockAcquire(pHT->Spinlock, &Tmp); 
    326         if (pHT->cAllocated < cNew) 
    327         { 
    328             /* copy the current table. */ 
    329             memcpy(paNew, pHT->paEntries, pHT->cAllocated * sizeof(*paNew)); 
    330  
    331             /* link the new entries into the free chain. */ 
    332             i = pHT->cAllocated; 
    333             uint32_t iTail = pHT->iTail; 
    334             if (iTail == UINT32_MAX) 
    335                 pHT->iHead = iTail = i++; 
    336             while (i < cNew) 
    337             { 
    338                 paNew[iTail].iNext = i; 
    339                 iTail = i++; 
    340             } 
    341             paNew[iTail].iNext = UINT32_MAX; 
    342             pHT->iTail = iTail; 
    343  
    344             /* update the handle table. */ 
    345             pHT->cAllocated = cNew; 
    346             paNew = (PINTNETHTE)ASMAtomicXchgPtr((void * volatile *)&pHT->paEntries, paNew); 
    347         } 
    348     } 
    349  
    350     if (paNew) 
    351         RTMemFree(paNew); 
    352     return INTNET_HANDLE_INVALID; 
    353 
    354  
    355  
    356 /** 
    357  * Validates and frees a handle. 
    358  * 
    359  * @returns Pointer to interface. 
    360  * @returns NULL if the handle is invalid. 
    361  * @param   pHT         Pointer to the handle table. 
    362  * @param   h           The handle we're freeing. 
    363  */ 
    364 static PINTNETIF intnetR0HandleFree(PINTNETHT pHT, INTNETIFHANDLE h) 
    365 
    366     RTSPINLOCKTMP   Tmp = RTSPINLOCKTMP_INITIALIZER; 
    367     RTSpinlockAcquire(pHT->Spinlock, &Tmp); 
    368  
    369     /* 
    370      * Validate and get it, then insert the handle table entry 
    371      * at the end of the free list. 
    372      */ 
    373     PINTNETIF pIF = intnetR0Handle2IFPtrLocked(pHT, h); 
    374     if (pIF) 
    375     { 
    376         const uint32_t i = h & INTNET_HANDLE_INDEX_MASK; 
    377         pHT->paEntries[i].iNext = UINT32_MAX; 
    378         const uint32_t iTail = pHT->iTail; 
    379         if (iTail != UINT32_MAX) 
    380             pHT->paEntries[iTail].iNext = i; 
    381         else 
    382             pHT->iHead = i; 
    383         pHT->iTail = i; 
    384     } 
    385  
    386     RTSpinlockRelease(pHT->Spinlock, &Tmp); 
    387  
    388     AssertMsg(pIF, ("%d >= %d\n", h & INTNET_HANDLE_INDEX_MASK, pHT->cAllocated)); 
    389     return pIF; 
     190 * Retain an interface. 
     191 * 
     192 * @returns VBox status code, can assume success in most situations. 
     193 * @param   pIf                 The interface instance. 
     194 * @param   pSession            The current session. 
     195 */ 
     196DECLINLINE(int) intnetR0IfRetain(PINTNETIF pIf, PSUPDRVSESSION pSession) 
     197
     198    int rc = SUPR0ObjAddRef(pIf->pvObj, pSession); 
     199    AssertRCReturn(rc, rc); 
     200    return VINF_SUCCESS; 
     201
     202 
     203 
     204/** 
     205 * Release an interface previously retained by intnetR0IfRetain or 
     206 * by handle lookup/freeing. 
     207 * 
     208 * @returns VBox status code, can assume success in most situations. 
     209 * @param   pIf                 The interface instance. 
     210 * @param   pSession            The current session. 
     211 */ 
     212DECLINLINE(void) intnetR0IfRelease(PINTNETIF pIf, PSUPDRVSESSION pSession) 
     213
     214    int rc = SUPR0ObjRelease(pIf->pvObj, pSession); 
     215    AssertRC(rc); 
     216
     217 
     218 
     219/** 
     220 * RTHandleCreateEx callback that retains an object in the 
     221 * handle table before returning it. 
     222 * 
     223 * (Avoids racing the freeing of the handle.) 
     224 * 
     225 * @returns VBox status code. 
     226 * @param   hHandleTable        The handle table (ignored). 
     227 * @param   pvObj               The object (INTNETIF). 
     228 * @param   pvCtx               The context (SUPDRVSESSION). 
     229 * @param   pvUser              The user context (ignored). 
     230 */ 
     231static DECLCALLBACK(int) intnetR0IfRetainHandle(RTHANDLETABLE hHandleTable, void *pvObj, void *pvCtx, void *pvUser) 
     232
     233    NOREF(pvUser); 
     234    NOREF(hHandleTable); 
     235    PINTNETIF pIf = (PINTNETIF)pvObj; 
     236    if (pIf->hIf != INTNET_HANDLE_INVALID) /* Don't try retain it if called from intnetR0IfDestruct. */ 
     237        return intnetR0IfRetain(pIf, (PSUPDRVSESSION)pvCtx); 
     238    return VINF_SUCCESS; 
    390239} 
    391240 
     
    991840INTNETR0DECL(int) INTNETR0IfSend(PINTNET pIntNet, INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, const void *pvFrame, unsigned cbFrame) 
    992841{ 
    993 //    LogFlow(("INTNETR0IfSend: pIntNet=%p hIf=%RX32 pvFrame=%p cbFrame=%u\n", pIntNet, hIf, pvFrame, cbFrame)); 
     842    Log5(("INTNETR0IfSend: pIntNet=%p hIf=%RX32 pvFrame=%p cbFrame=%u\n", pIntNet, hIf, pvFrame, cbFrame)); 
    994843 
    995844    /* 
    996845     * Validate input and translate the handle. 
    997846     */ 
    998     /** @todo add an exctra reference to the interface! */ 
    999847    AssertReturn(pIntNet, VERR_INVALID_PARAMETER); 
    1000     PINTNETIF pIf = intnetR0Handle2IFPtr(&pIntNet->IfHandles, hIf); 
    1001     if (!pIf) 
    1002         return VERR_INVALID_HANDLE; 
    1003848    if (pvFrame && cbFrame) 
    1004849    { 
     
    1010855        ASMProbeReadBuffer(pvFrame, cbFrame); 
    1011856    } 
     857    PINTNETIF pIf = (PINTNETIF)RTHandleTableLookupWithCtx(pIntNet->hHtIfs, hIf, pSession); 
     858    if (!pIf) 
     859        return VERR_INVALID_HANDLE; 
    1012860 
    1013861    /* 
     
    1021869    int rc = RTSemFastMutexRequest(pNetwork->FastMutex); 
    1022870    if (RT_FAILURE(rc)) 
     871    { 
     872        intnetR0IfRelease(pIf, pSession); 
    1023873        return rc; 
     874    } 
    1024875    PINTNETTRUNKIF pTrunkIf = intnetR0TrunkIfRetain(pNetwork->pTrunkIF); 
    1025876    if (pTrunkIf) 
     
    1030881        { 
    1031882            intnetR0TrunkIfRelease(pTrunkIf); 
     883            intnetR0IfRelease(pIf, pSession); 
    1032884            return VERR_SEM_DESTROYED; 
    1033885        } 
     
    1038890            intnetR0TrunkIfOutUnlock(pTrunkIf); 
    1039891            intnetR0TrunkIfRelease(pTrunkIf); 
     892            intnetR0IfRelease(pIf, pSession); 
    1040893            return rc; 
    1041894        } 
     
    1087940    } 
    1088941 
     942    intnetR0IfRelease(pIf, pSession); 
    1089943    return rc; 
    1090944} 
     
    1124978     */ 
    1125979    AssertReturn(pIntNet, VERR_INVALID_PARAMETER); 
    1126     PINTNETIF pIf = intnetR0Handle2IFPtr(&pIntNet->IfHandles, hIf); 
     980    AssertPtrReturn(ppRing3Buf, VERR_INVALID_PARAMETER); 
     981    *ppRing3Buf = 0; 
     982    PINTNETIF pIf = (PINTNETIF)RTHandleTableLookupWithCtx(pIntNet->hHtIfs, hIf, pSession); 
    1127983    if (!pIf) 
    1128984        return VERR_INVALID_HANDLE; 
    1129     AssertPtrReturn(ppRing3Buf, VERR_INVALID_PARAMETER); 
    1130985 
    1131986    /* 
     
    1135990     */ 
    1136991    int rc = RTSemFastMutexRequest(pIf->pNetwork->FastMutex); 
    1137     if (RT_FAILURE(rc)) 
    1138         return rc; 
    1139  
    1140     *ppRing3Buf = pIf->pIntBufR3; 
    1141  
    1142     rc = RTSemFastMutexRelease(pIf->pNetwork->FastMutex); 
     992    if (RT_SUCCESS(rc)) 
     993    { 
     994        *ppRing3Buf = pIf->pIntBufR3; 
     995        rc = RTSemFastMutexRelease(pIf->pNetwork->FastMutex); 
     996    } 
     997 
     998    intnetR0IfRelease(pIf, pSession); 
    1143999    LogFlow(("INTNETR0IfGetRing3Buffer: returns %Rrc *ppRing3Buf=%p\n", rc, *ppRing3Buf)); 
    11441000    return rc; 
     
    11661022 * 
    11671023 * @returns VBox status code. 
    1168  * @param   pIntNet     The instance data. 
    1169  * @param   hIf         The interface handle. 
    1170  * @param   ppRing0Buf  Where to store the address of the ring-3 mapping. 
    1171  */ 
    1172 INTNETR0DECL(int) INTNETR0IfGetRing0Buffer(PINTNET pIntNet, INTNETIFHANDLE hIf, PINTNETBUF *ppRing0Buf) 
     1024 * @param   pIntNet         The instance data. 
     1025 * @param   hIf             The interface handle. 
     1026 * @param   pSession        The caller's session. 
     1027 * @param   ppRing0Buf      Where to store the address of the ring-3 mapping. 
     1028 */ 
     1029INTNETR0DECL(int) INTNETR0IfGetRing0Buffer(PINTNET pIntNet, INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, PINTNETBUF *ppRing0Buf) 
    11731030{ 
    11741031    LogFlow(("INTNETR0IfGetRing0Buffer: pIntNet=%p hIf=%RX32 ppRing0Buf=%p\n", pIntNet, hIf, ppRing0Buf)); 
     
    11801037    *ppRing0Buf = NULL; 
    11811038    AssertPtrReturn(pIntNet, VERR_INVALID_PARAMETER); 
    1182     PINTNETIF pIf = intnetR0Handle2IFPtr(&pIntNet->IfHandles, hIf); 
     1039    PINTNETIF pIf = (PINTNETIF)RTHandleTableLookupWithCtx(pIntNet->hHtIfs, hIf, pSession); 
    11831040    if (!pIf) 
    11841041        return VERR_INVALID_HANDLE; 
     
    11891046     */ 
    11901047    int rc = RTSemFastMutexRequest(pIf->pNetwork->FastMutex); 
    1191     if (RT_FAILURE(rc)) 
    1192         return rc; 
    1193  
    1194     *ppRing0Buf = pIf->pIntBuf; 
    1195  
    1196     rc = RTSemFastMutexRelease(pIf->pNetwork->FastMutex); 
     1048    if (RT_SUCCESS(rc)) 
     1049    { 
     1050        *ppRing0Buf = pIf->pIntBuf; 
     1051 
     1052        rc = RTSemFastMutexRelease(pIf->pNetwork->FastMutex); 
     1053    } 
     1054    intnetR0IfRelease(pIf, pSession); 
    11971055    LogFlow(("INTNETR0IfGetRing0Buffer: returns %Rrc *ppRing0Buf=%p\n", rc, *ppRing0Buf)); 
    11981056    return rc; 
     
    12161074     */ 
    12171075    AssertReturn(pIntNet, VERR_INVALID_PARAMETER); 
    1218     PINTNETIF pIf = intnetR0Handle2IFPtr(&pIntNet->IfHandles, hIf); 
     1076    AssertPtrReturn(paPages, VERR_INVALID_PARAMETER); 
     1077    AssertPtrReturn((uint8_t *)&paPages[cPages] - 1, VERR_INVALID_PARAMETER); 
     1078    PINTNETIF pIf = (PINTNETIF)RTHandleTableLookupWithCtx(pIntNet->hHtIfs, hIf, pSession); 
    12191079    if (!pIf) 
    12201080        return VERR_INVALID_HANDLE; 
    1221     AssertPtrReturn(paPages, VERR_INVALID_PARAMETER); 
    1222     AssertPtrReturn((uint8_t *)&paPages[cPages] - 1, VERR_INVALID_PARAMETER); 
    12231081 
    12241082    /* 
     
    12271085     */ 
    12281086    int rc = RTSemFastMutexRequest(pIf->pNetwork->FastMutex); 
    1229     if (RT_FAILURE(rc)) 
    1230         return rc; 
    1231  
    1232     /** @todo make a SUPR0 api for obtaining the array. SUPR0/IPRT is keeping track of everything, there 
    1233      * is no need for any extra bookkeeping here.. */ 
    1234     //*ppRing0Buf = pIf->pIntBuf; 
    1235  
    1236     //return RTSemFastMutexRelease(pIf->pNetwork->FastMutex); 
    1237     RTSemFastMutexRelease(pIf->pNetwork->FastMutex); 
     1087    if (RT_SUCCESS(rc)) 
     1088    { 
     1089        /** @todo make a SUPR0 api for obtaining the array. SUPR0/IPRT is keeping track of everything, there 
     1090         * is no need for any extra bookkeeping here.. */ 
     1091 
     1092        rc = RTSemFastMutexRelease(pIf->pNetwork->FastMutex); 
     1093    } 
     1094    intnetR0IfRelease(pIf, pSession); 
    12381095    return VERR_NOT_IMPLEMENTED; 
    12391096} 
     
    12581115     */ 
    12591116    AssertReturn(pIntNet, VERR_INVALID_PARAMETER); 
    1260     PINTNETIF pIf = intnetR0Handle2IFPtr(&pIntNet->IfHandles, hIf); 
     1117    PINTNETIF pIf = (PINTNETIF)RTHandleTableLookupWithCtx(pIntNet->hHtIfs, hIf, pSession); 
    12611118    if (!pIf) 
    12621119    { 
    1263         LogFlow(("INTNETR0IfSetPromiscuousMode: returns VERR_INVALID_HANDLE\n")); 
     1120        Log(("INTNETR0IfSetPromiscuousMode: returns VERR_INVALID_HANDLE\n")); 
    12641121        return VERR_INVALID_HANDLE; 
    12651122    } 
     
    12681125     * Grab the network semaphore and make the change. 
    12691126     */ 
     1127    int rc; 
    12701128    PINTNETNETWORK pNetwork = pIf->pNetwork; 
    1271     if (!pNetwork) 
    1272         return VERR_WRONG_ORDER; 
    1273     int rc = RTSemFastMutexRequest(pNetwork->FastMutex); 
    1274     if (RT_FAILURE(rc)) 
    1275         return rc; 
    1276  
    1277     if (pIf->fPromiscuous != fPromiscuous) 
    1278     { 
    1279         Log(("INTNETR0IfSetPromiscuousMode: hIf=%RX32: Changed from %d -> %d\n", 
    1280              hIf, !fPromiscuous, !!fPromiscuous)); 
    1281         ASMAtomicUoWriteBool(&pIf->fPromiscuous, fPromiscuous); 
    1282     } 
    1283  
    1284     RTSemFastMutexRelease(pNetwork->FastMutex); 
    1285     return VINF_SUCCESS; 
     1129    if (pNetwork) 
     1130    { 
     1131        rc = RTSemFastMutexRequest(pNetwork->FastMutex); 
     1132        if (RT_SUCCESS(rc)) 
     1133        { 
     1134            if (pIf->fPromiscuous != fPromiscuous) 
     1135            { 
     1136                Log(("INTNETR0IfSetPromiscuousMode: hIf=%RX32: Changed from %d -> %d\n", 
     1137                     hIf, !fPromiscuous, !!fPromiscuous)); 
     1138                ASMAtomicUoWriteBool(&pIf->fPromiscuous, fPromiscuous); 
     1139            } 
     1140 
     1141            rc = RTSemFastMutexRelease(pNetwork->FastMutex); 
     1142        } 
     1143    } 
     1144    else 
     1145        rc = VERR_WRONG_ORDER; 
     1146 
     1147    intnetR0IfRelease(pIf, pSession); 
     1148    return rc; 
    12861149} 
    12871150 
     
    14091272INTNETR0DECL(int) INTNETR0IfWait(PINTNET pIntNet, INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, uint32_t cMillies) 
    14101273{ 
    1411 //    LogFlow(("INTNETR0IfWait: pIntNet=%p hIf=%RX32 cMillies=%u\n", pIntNet, hIf, cMillies)); 
     1274    Log4(("INTNETR0IfWait: pIntNet=%p hIf=%RX32 cMillies=%u\n", pIntNet, hIf, cMillies)); 
    14121275 
    14131276    /* 
    14141277     * Get and validate essential handles. 
    14151278     */ 
    1416     AssertReturn(pIntNet, VERR_INVALID_PARAMETER); 
    1417     PINTNETIF pIf = intnetR0Handle2IFPtr(&pIntNet->IfHandles, hIf); 
     1279    AssertPtrReturn(pIntNet, VERR_INVALID_PARAMETER); 
     1280    PINTNETIF pIf = (PINTNETIF)RTHandleTableLookupWithCtx(pIntNet->hHtIfs, hIf, pSession); 
    14181281    if (!pIf) 
    14191282    { 
    1420         LogFlow(("INTNETR0IfWait: returns VERR_INVALID_HANDLE\n")); 
     1283        Log(("INTNETR0IfWait: returns VERR_INVALID_HANDLE\n")); 
    14211284        return VERR_INVALID_HANDLE; 
    14221285    } 
    14231286    const INTNETIFHANDLE    hIfSelf = pIf->hIf; 
    14241287    const RTSEMEVENT        Event = pIf->Event; 
    1425     if (    hIfSelf != hIf 
     1288    if (    hIfSelf != hIf              /* paranoia */ 
    14261289        &&  Event != NIL_RTSEMEVENT) 
    14271290    { 
    1428         LogFlow(("INTNETR0IfWait: returns VERR_SEM_DESTROYED\n")); 
     1291        Log(("INTNETR0IfWait: returns VERR_SEM_DESTROYED\n")); 
    14291292        return VERR_SEM_DESTROYED; 
    14301293    } 
     
    14391302    /* 
    14401303     * Increment the number of waiters before starting the wait. 
    1441      * Upon wakeup we must assert reality checking that we're not 
    1442      * already destroyed or in the process of being destroyed. 
     1304     * Upon wakeup we must assert reality, checking that we're not 
     1305     * already destroyed or in the process of being destroyed. This 
     1306     * code must be aligned with the waiting code in intnetR0IfDestruct. 
    14431307     */ 
    14441308    ASMAtomicIncU32(&pIf->cSleepers); 
     
    14471311    { 
    14481312        ASMAtomicDecU32(&pIf->cSleepers); 
    1449         if (pIf->hIf != hIf) 
     1313        if (!pIf->fDestroying) 
     1314        { 
     1315            intnetR0IfRelease(pIf, pSession); 
     1316            if (pIf->hIf != hIf) 
     1317                rc = VERR_SEM_DESTROYED; 
     1318        } 
     1319        else 
    14501320            rc = VERR_SEM_DESTROYED; 
    14511321    } 
    14521322    else 
    14531323        rc = VERR_SEM_DESTROYED; 
    1454 //    LogFlow(("INTNETR0IfWait: returns %Rrc\n", rc)); 
     1324    Log4(("INTNETR0IfWait: returns %Rrc\n", rc)); 
    14551325    return rc; 
    14561326} 
     
    14861356 
    14871357    /* 
    1488      * Validate, get and free the handle. 
     1358     * Validate and free the handle. 
    14891359     */ 
    14901360    AssertPtrReturn(pIntNet, VERR_INVALID_PARAMETER); 
    1491     PINTNETIF pIf = intnetR0HandleFree(&pIntNet->IfHandles, hIf); 
     1361    PINTNETIF pIf = (PINTNETIF)RTHandleTableFreeWithCtx(pIntNet->hHtIfs, hIf, pSession); 
    14921362    if (!pIf) 
    14931363        return VERR_INVALID_HANDLE; 
     1364 
     1365    /* mark the handle as freed so intnetR0IfDestruct won't free it again. */ 
    14941366    ASMAtomicWriteU32(&pIf->hIf, INTNET_HANDLE_INVALID); 
    14951367 
    1496     /* 
    1497      * Release our reference to the interface object. 
    1498      */ 
    1499     int rc = SUPR0ObjRelease(pIf->pvObj, pIf->pSession); 
     1368 
     1369    /* 
     1370     * Release the references to the interface object (handle + free lookup). 
     1371     * But signal the event semaphore first so any waiter holding a reference 
     1372     * will wake up too (he'll see hIf == invalid and return correctly). 
     1373     */ 
     1374    RTSemEventSignal(pIf->Event); 
     1375 
     1376    void *pvObj = pIf->pvObj; 
     1377    intnetR0IfRelease(pIf, pSession); /* (RTHandleTableFreeWithCtx) */ 
     1378 
     1379    int rc = SUPR0ObjRelease(pvObj, pSession); 
    15001380    LogFlow(("INTNETR0IfClose: returns %Rrc\n", rc)); 
    15011381    return rc; 
     
    15361416 
    15371417    /* 
    1538      * Delete the interface handle so the object no longer can be opened. 
     1418     * Mark the interface as being destroyed so the waiter 
     1419     * can behave appropriately (theoretical case). 
     1420     */ 
     1421    ASMAtomicWriteBool(&pIf->fDestroying, true); 
     1422 
     1423    /* 
     1424     * Delete the interface handle so the object no longer can be used. 
     1425     * (Can happen if the client didn't close its session.) 
    15391426     */ 
    15401427    INTNETIFHANDLE hIf = ASMAtomicXchgU32(&pIf->hIf, INTNET_HANDLE_INVALID); 
    15411428    if (hIf != INTNET_HANDLE_INVALID) 
    1542         intnetR0HandleFree(&pIntNet->IfHandles, hIf); 
     1429    { 
     1430        void *pvObj2 = RTHandleTableFreeWithCtx(pIntNet->hHtIfs, hIf, pIf->pSession); 
     1431        AssertMsg(pvObj2 == pIf, ("%p, %p, hIf=%#x pSession=%p\n", pvObj2, pIf, hIf, pIf->pSession)); 
     1432    } 
    15431433 
    15441434    /* 
     
    15891479    { 
    15901480        RTSEMEVENT Event = pIf->Event; 
    1591         ASMAtomicXchgSize(&pIf->Event, NIL_RTSEMEVENT); 
    15921481        unsigned cMaxWait = 0x1000; 
    15931482        while (pIf->cSleepers && cMaxWait-- > 0) 
     
    16071496            } 
    16081497        } 
     1498 
    16091499        RTSemEventDestroy(Event); 
     1500        pIf->Event = NIL_RTSEMEVENT; 
    16101501    } 
    16111502 
     
    16771568    //pIf->fPromiscuous = false; 
    16781569    //pIf->fActive = false; 
     1570    //pIf->fDestroying = false; 
    16791571    //pIf->pIntBuf = 0; 
    16801572    //pIf->pIntBufR3 = NIL_RTR3PTR; 
     
    16881580    pIf->pSession = pSession; 
    16891581    //pIf->pvObj = NULL; 
    1690     int rc = RTSemEventCreate(&pIf->Event); 
     1582    int rc = RTSemEventCreate((PRTSEMEVENT)&pIf->Event); 
    16911583    if (RT_SUCCESS(rc)) 
    16921584    { 
     
    17351627                if (pIf->pvObj) 
    17361628                { 
    1737                     pIf->hIf = intnetR0HandleAllocate(pNetwork->pIntNet, pIf); 
    1738                     if (pIf->hIf != INTNET_HANDLE_INVALID
     1629                    rc = RTHandleTableAllocWithCtx(pNetwork->pIntNet->hHtIfs, pIf, pSession, (uint32_t *)&pIf->hIf); 
     1630                    if (RT_SUCCESS(rc)
    17391631                    { 
    17401632                        /* auto activation */ /** @todo do this manually in the future, ditto for setting the MAC address. */ 
     
    17471639                        return VINF_SUCCESS; 
    17481640                    } 
    1749                     rc = VERR_NO_MEMORY; 
    17501641 
    17511642                    SUPR0ObjRelease(pIf->pvObj, pSession); 
     
    17541645                } 
    17551646 
    1756                 rc = VERR_NO_MEMORY; 
    17571647                RTSemFastMutexDestroy(pNetwork->FastMutex); 
    17581648                pNetwork->FastMutex = NIL_RTSEMFASTMUTEX; 
     
    25472437        pIntNet->FastMutex = NIL_RTSEMFASTMUTEX; 
    25482438    } 
    2549     if (pIntNet->IfHandles.Spinlock != NIL_RTSPINLOCK) 
    2550     { 
    2551         RTSpinlockDestroy(pIntNet->IfHandles.Spinlock); 
    2552         pIntNet->IfHandles.Spinlock = NIL_RTSPINLOCK; 
     2439    if (pIntNet->hHtIfs != NIL_RTHANDLETABLE) 
     2440    { 
     2441        /** @todo does it make sense to have a deleter here? */ 
     2442        RTHandleTableDestroy(pIntNet->hHtIfs, NULL, NULL); 
     2443        pIntNet->hHtIfs = NIL_RTHANDLETABLE; 
    25532444    } 
    25542445 
     
    25712462    { 
    25722463        //pIntNet->pNetworks              = NULL; 
    2573         //pIntNet->IfHandles.paEntries    = NULL; 
    2574         //pIntNet->IfHandles.cAllocated   = 0; 
    2575         pIntNet->IfHandles.iHead        = UINT32_MAX; 
    2576         pIntNet->IfHandles.iTail        = UINT32_MAX; 
    25772464 
    25782465        rc = RTSemFastMutexCreate(&pIntNet->FastMutex); 
    25792466        if (RT_SUCCESS(rc)) 
    25802467        { 
    2581             rc = RTSpinlockCreate(&pIntNet->IfHandles.Spinlock); 
     2468            rc = RTHandleTableCreateEx(&pIntNet->hHtIfs, RTHANDLETABLE_FLAGS_LOCKED | RTHANDLETABLE_FLAGS_CONTEXT, 
     2469                                       UINT32_C(0x8ffe0000), 4096, intnetR0IfRetainHandle, NULL); 
    25822470            if (RT_SUCCESS(rc)) 
    25832471            { 
     
    25862474                return VINF_SUCCESS; 
    25872475            } 
     2476 
    25882477            RTSemFastMutexDestroy(pIntNet->FastMutex); 
    25892478        } 
  • trunk/src/VBox/Devices/Network/testcase/tstIntNetR0.cpp

    r10806 r10819  
    3434#undef DECLR0CALLBACKMEMBER 
    3535#define DECLR0CALLBACKMEMBER(type, name, args) DECLR3CALLBACKMEMBER(type, name, args) 
     36#include <VBox/types.h> 
     37typedef void *MYPSUPDRVSESSION; 
     38#define PSUPDRVSESSION  MYPSUPDRVSESSION 
     39 
    3640#include <VBox/intnet.h> 
    3741#include <VBox/sup.h> 
     
    8993    uint32_t volatile cRefs; 
    9094} OBJREF, *POBJREF; 
     95 
    9196 
    9297/******************************************************************************* 
     
    450455                { 
    451456                    PINTNETBUF pBuf0; 
    452                     rc = INTNETR0IfGetRing0Buffer(pIntNet, hIf0, &pBuf0); 
     457                    rc = INTNETR0IfGetRing0Buffer(pIntNet, hIf0, g_pSession, &pBuf0); 
    453458                    if (VBOX_FAILURE(rc) || !pBuf0) 
    454459                    { 
     
    457462                    } 
    458463                    PINTNETBUF pBuf1; 
    459                     rc = INTNETR0IfGetRing0Buffer(pIntNet, hIf1, &pBuf1); 
     464                    rc = INTNETR0IfGetRing0Buffer(pIntNet, hIf1, g_pSession, &pBuf1); 
    460465                    if (VBOX_FAILURE(rc)) 
    461466                    { 

© 2008 Sun Microsystems, Inc.
ContactPrivacy policy