VirtualBox

Changeset 3521 in vbox for trunk/src/VBox/Devices


Ignore:
Timestamp:
Jul 10, 2007 11:40:06 AM (17 years ago)
Author:
vboxsync
Message:

Unfinished code.

File:
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Network/DrvTAPOs2.cpp

    r3481 r3521  
     1/** $Id$ */
    12/** @file
    2  *
    3  * VBox network devices:
    4  * Linux TAP network transport driver
     3 * VBox network devices: OS/2 TAP network transport driver.
    54 */
    65
     
    2221 *
    2322 */
    24 
    25 #define ASYNC_NET
    2623
    2724/*******************************************************************************
     
    3835#include <iprt/file.h>
    3936#include <iprt/string.h>
    40 #ifdef ASYNC_NET
    4137#include <iprt/thread.h>
    4238#include <iprt/asm.h>
    4339#include <iprt/semaphore.h>
    44 #endif
    45 
    46 #include <sys/ioctl.h>
    47 #include <sys/poll.h>
    48 #include <sys/fcntl.h>
    49 #include <errno.h>
    50 #ifdef ASYNC_NET
    51 #include <unistd.h>
    52 #endif
    5340
    5441#include "Builtins.h"
     42
    5543
    5644
     
    5846*   Structures and Typedefs                                                    *
    5947*******************************************************************************/
    60 typedef enum ASYNCSTATE
    61 {
    62     //ASYNCSTATE_SUSPENDED = 1,
    63     ASYNCSTATE_RUNNING,
    64     ASYNCSTATE_TERMINATE
    65 } ASYNCSTATE;
    6648
    6749/**
    6850 * Block driver instance data.
    6951 */
    70 typedef struct DRVTAP
     52typedef struct DRVTAPOS2
    7153{
    7254    /** The network interface. */
     
    7860    /** TAP device file handle. */
    7961    RTFILE                  FileDevice;
    80 #ifdef ASYNC_NET
    81     /** The write end of the control pipe. */
    82     RTFILE                  PipeWrite;
    83     /** The read end of the control pipe. */
    84     RTFILE                  PipeRead;
    85     /** The thread state. */
    86     ASYNCSTATE volatile     enmState;
    87     /** Reader thread. */
    88     RTTHREAD                Thread;
     62    /** Receiver thread. */
     63    PPDMTHREAD              pThread;
    8964    /** We are waiting for more receive buffers. */
    9065    uint32_t volatile       fOutOfSpace;
    9166    /** Event semaphore for blocking on receive. */
    9267    RTSEMEVENT              EventOutOfSpace;
    93 #endif
    9468
    9569#ifdef VBOX_WITH_STATISTICS
     
    10680    /** Profiling packet receive runs. */
    10781    STAMPROFILEADV          StatReceive;
    108 #ifdef ASYNC_NET
    10982    STAMPROFILE             StatRecvOverflows;
    110 #endif
    11183#endif /* VBOX_WITH_STATISTICS */
    11284
     
    11789    uint64_t                u64LastReceiveTS;
    11890#endif
    119 } DRVTAP, *PDRVTAP;
     91} DRVTAPOS2, *PDRVTAPOS2;
    12092
    12193
    12294/** Converts a pointer to TAP::INetworkConnector to a PRDVTAP. */
    123 #define PDMINETWORKCONNECTOR_2_DRVTAP(pInterface) ( (PDRVTAP)((uintptr_t)pInterface - RT_OFFSETOF(DRVTAP, INetworkConnector)) )
     95#define PDMINETWORKCONNECTOR_2_DRVTAPOS2(pInterface) ( (PDRVTAPOS2)((uintptr_t)pInterface - RT_OFFSETOF(DRVTAPOS2, INetworkConnector)) )
    12496
    12597
     
    133105 * @thread  EMT
    134106 */
    135 static DECLCALLBACK(int) drvTAPSend(PPDMINETWORKCONNECTOR pInterface, const void *pvBuf, size_t cb)
    136 {
    137     PDRVTAP pData = PDMINETWORKCONNECTOR_2_DRVTAP(pInterface);
     107static DECLCALLBACK(int) drvTAPOs2Send(PPDMINETWORKCONNECTOR pInterface, const void *pvBuf, size_t cb)
     108{
     109    PDRVTAPOS2 pData = PDMINETWORKCONNECTOR_2_DRVTAPOS2(pInterface);
    138110    STAM_COUNTER_INC(&pData->StatPktSent);
    139111    STAM_COUNTER_ADD(&pData->StatPktSentBytes, cb);
     
    142114#ifdef LOG_ENABLED
    143115    uint64_t u64Now = RTTimeProgramNanoTS();
    144     LogFlow(("drvTAPSend: %-4d bytes at %llu ns  deltas: r=%llu t=%llu\n",
     116    LogFlow(("drvTAPOs2Send: %-4d bytes at %llu ns  deltas: r=%llu t=%llu\n",
    145117             cb, u64Now, u64Now - pData->u64LastReceiveTS, u64Now - pData->u64LastTransferTS));
    146118    pData->u64LastTransferTS = u64Now;
    147119#endif
    148     Log2(("drvTAPSend: pvBuf=%p cb=%#x\n"
     120    Log2(("drvTAPOs2Send: pvBuf=%p cb=%#x\n"
    149121          "%.*Vhxd\n",
    150122          pvBuf, cb, cb, pvBuf));
    151123
    152     int rc = RTFileWrite(pData->FileDevice, pvBuf, cb, NULL);
     124    ULONG UnusedParms[10] = { 0,0,0,0, 0,0,0,0, 0,0 };
     125    ULONG cbParms = sizeof(UnusedParms);
     126    ULONG cbData = cb;
     127    int rc = DosDevIOCtl(pData->FileDevice, PROT_CATEGORY, TAP_WRITE_PACKET,
     128                         &UnusedParms[0], cbParms, &cbParms,
     129                         pvBuf, cbData, &cbData);
     130    if (rc)
     131        rc = RTErrConvertFromOS2(rc);
    153132
    154133    STAM_PROFILE_STOP(&pData->StatTransmit, a);
     
    168147 * @thread  EMT
    169148 */
    170 static DECLCALLBACK(void) drvTAPSetPromiscuousMode(PPDMINETWORKCONNECTOR pInterface, bool fPromiscuous)
    171 {
    172     LogFlow(("drvTAPSetPromiscuousMode: fPromiscuous=%d\n", fPromiscuous));
     149static DECLCALLBACK(void) drvTAPOs2SetPromiscuousMode(PPDMINETWORKCONNECTOR pInterface, bool fPromiscuous)
     150{
     151    LogFlow(("drvTAPOs2SetPromiscuousMode: fPromiscuous=%d\n", fPromiscuous));
    173152    /* nothing to do */
    174153}
     
    182161 * @thread  EMT
    183162 */
    184 static DECLCALLBACK(void) drvTAPNotifyLinkChanged(PPDMINETWORKCONNECTOR pInterface, PDMNETWORKLINKSTATE enmLinkState)
     163static DECLCALLBACK(void) drvTAPOs2NotifyLinkChanged(PPDMINETWORKCONNECTOR pInterface, PDMNETWORKLINKSTATE enmLinkState)
    185164{
    186165    LogFlow(("drvNATNotifyLinkChanged: enmLinkState=%d\n", enmLinkState));
     
    197176 * @thread  EMT
    198177 */
    199 static DECLCALLBACK(void) drvTAPNotifyCanReceive(PPDMINETWORKCONNECTOR pInterface)
    200 {
    201     PDRVTAP pData = PDMINETWORKCONNECTOR_2_DRVTAP(pInterface);
    202 
    203     LogFlow(("drvTAPNotifyCanReceive:\n"));
     178static DECLCALLBACK(void) drvTAPOs2NotifyCanReceive(PPDMINETWORKCONNECTOR pInterface)
     179{
     180    PDRVTAPOS2 pData = PDMINETWORKCONNECTOR_2_DRVTAPOS2(pInterface);
     181
     182    LogFlow(("drvTAPOs2NotifyCanReceive:\n"));
    204183    /* ensure we wake up only once */
    205184    if (ASMAtomicXchgU32(&pData->fOutOfSpace, false))
     
    208187
    209188
    210 #ifdef ASYNC_NET
    211189/**
    212190 * Asynchronous I/O thread for handling receive.
    213191 *
    214192 * @returns VINF_SUCCESS (ignored).
    215  * @param   Thread          Thread handle.
    216  * @param   pvUser          Pointer to a DRVTAP structure.
    217  */
    218 static DECLCALLBACK(int) drvTAPAsyncIoThread(RTTHREAD ThreadSelf, void *pvUser)
    219 {
    220     PDRVTAP pData = (PDRVTAP)pvUser;
    221     LogFlow(("drvTAPAsyncIoThread: pData=%p\n", pData));
    222     STAM_PROFILE_ADV_START(&pData->StatReceive, a);
    223 
    224     int rc = RTSemEventCreate(&pData->EventOutOfSpace);
    225     AssertRC(rc);
    226 
    227     /*
    228      * Polling loop.
     193 * @param   pDrvIns         The driver instance.
     194 * @param   pThread         The PDM thread structure.
     195 */
     196static DECLCALLBACK(int) drvTAPOs2AsyncIoThread(PPDMDRVINS pDrvIns, PPDMTHREAD pThread)
     197{
     198    PDRVTAPOS2 pData = PDMINS2DATA(pDrvIns, PDRVTAPOS2);
     199    LogFlow(("drvTAPOs2AsyncIoThread: pData=%p\n", pData));
     200    Assert(pThread->enmState == PDMTHREADSTATE_INITIALIZING);
     201   
     202
     203    /*
     204     * Outer loop.
    229205     */
    230206    for (;;)
    231207    {
    232208        /*
    233          * Wait for something to become available.
     209         *
    234210         */
    235         struct pollfd aFDs[2];
    236         aFDs[0].fd      = pData->FileDevice;
    237         aFDs[0].events  = POLLIN | POLLPRI;
    238         aFDs[0].revents = 0;
    239         aFDs[1].fd      = pData->PipeRead;
    240         aFDs[1].events  = POLLIN | POLLPRI | POLLERR | POLLHUP;
    241         aFDs[1].revents = 0;
    242         STAM_PROFILE_ADV_STOP(&pData->StatReceive, a);
    243         errno=0;
    244         rc = poll(&aFDs[0], ELEMENTS(aFDs), -1 /* infinite */);
    245         STAM_PROFILE_ADV_START(&pData->StatReceive, a);
    246         if (    rc > 0
    247             &&  (aFDs[0].revents & (POLLIN | POLLPRI))
    248             &&  !aFDs[1].revents)
     211        PDMR3ThreadSuspend(pThread);
     212        if (pThread->enmState != PDMTHREADSTATE_RESUMING)
     213            break;
     214
    249215        {
     216        }
     217    }
     218
     219
     220
     221
     222    STAM_PROFILE_ADV_START(&pData->StatReceive, a);
     223
     224    /*
     225     * Polling loop.
     226     */
     227    for (;;)
     228    {
     229        /*
     230         * Read/wait the frame.
     231         */
     232        char    achBuf[4096];
     233        ULONG   cbParm = ;
     234        ULONG   cbRead = 0;
     235        int     LanNumber;
     236
     237        int rc = DosDevIOCtl(pData->FileDevice, PROT_CATEGORY, TAP_CANCEL_READ,
     238                             &UnusedParms[0], cbParm, &cbParm,
     239                             &achBuf[0], cbRead, &cbRead);
     240        if (rc == NO_ERROR)
     241        {
     242            AssertMsg(cbRead <= 1536, ("cbRead=%d\n", cbRead));
     243
    250244            /*
    251              * Read the frame.
     245             * Wait for the device to have space for this frame.
    252246             */
    253             char achBuf[4096];
    254             unsigned cbRead = 0;
    255             rc = RTFileRead(pData->FileDevice, achBuf, sizeof(achBuf), &cbRead);
    256             if (VBOX_SUCCESS(rc))
     247            size_t cbMax = pData->pPort->pfnCanReceive(pData->pPort);
     248            if (cbMax < cbRead)
    257249            {
    258                 AssertMsg(cbRead <= 1536, ("cbRead=%d\n", cbRead));
    259 
    260                 /*
    261                  * Wait for the device to have space for this frame.
    262                  */
    263                 size_t cbMax = pData->pPort->pfnCanReceive(pData->pPort);
    264                 if (cbMax < cbRead)
     250                /** @todo receive overflow handling needs serious improving! */
     251                STAM_PROFILE_ADV_STOP(&pData->StatReceive, a);
     252                STAM_PROFILE_START(&pData->StatRecvOverflows, b);
     253                while (   cbMax < cbRead
     254                       && pData->enmState != ASYNCSTATE_TERMINATE)
    265255                {
    266                     /** @todo receive overflow handling needs serious improving! */
    267                     STAM_PROFILE_ADV_STOP(&pData->StatReceive, a);
    268                     STAM_PROFILE_START(&pData->StatRecvOverflows, b);
    269                     while (   cbMax < cbRead
    270                            && pData->enmState != ASYNCSTATE_TERMINATE)
    271                     {
    272                         LogFlow(("drvTAPAsyncIoThread: cbMax=%d cbRead=%d waiting...\n", cbMax, cbRead));
     256                    LogFlow(("drvTAPOs2AsyncIoThread: cbMax=%d cbRead=%d waiting...\n", cbMax, cbRead));
    273257#if 1
    274                         /* We get signalled by the network driver. 50ms is just for sanity */
    275                         ASMAtomicXchgU32(&pData->fOutOfSpace, true);
    276                         RTSemEventWait(pData->EventOutOfSpace, 50);
     258                    /* We get signalled by the network driver. 50ms is just for sanity */
     259                    ASMAtomicXchgU32(&pData->fOutOfSpace, true);
     260                    RTSemEventWait(pData->EventOutOfSpace, 50);
    277261#else
    278                         RTThreadSleep(1);
     262                    RTThreadSleep(1);
    279263#endif
    280                         cbMax = pData->pPort->pfnCanReceive(pData->pPort);
    281                     }
    282                     ASMAtomicXchgU32(&pData->fOutOfSpace, false);
    283                     STAM_PROFILE_STOP(&pData->StatRecvOverflows, b);
    284                     STAM_PROFILE_ADV_START(&pData->StatReceive, a);
    285                     if (pData->enmState == ASYNCSTATE_TERMINATE)
    286                         break;
     264                    cbMax = pData->pPort->pfnCanReceive(pData->pPort);
    287265                }
    288 
    289                 /*
    290                  * Pass the data up.
    291                  */
     266                ASMAtomicXchgU32(&pData->fOutOfSpace, false);
     267                STAM_PROFILE_STOP(&pData->StatRecvOverflows, b);
     268                STAM_PROFILE_ADV_START(&pData->StatReceive, a);
     269                if (pData->enmState == ASYNCSTATE_TERMINATE)
     270                    break;
     271            }
     272
     273            /*
     274             * Pass the data up.
     275             */
    292276#ifdef LOG_ENABLED
    293                 uint64_t u64Now = RTTimeProgramNanoTS();
    294                 LogFlow(("drvTAPAsyncIoThread: %-4d bytes at %llu ns  deltas: r=%llu t=%llu\n",
    295                          cbRead, u64Now, u64Now - pData->u64LastReceiveTS, u64Now - pData->u64LastTransferTS));
    296                 pData->u64LastReceiveTS = u64Now;
     277            uint64_t u64Now = RTTimeProgramNanoTS();
     278            LogFlow(("drvTAPOs2AsyncIoThread: %-4d bytes at %llu ns  deltas: r=%llu t=%llu\n",
     279                     cbRead, u64Now, u64Now - pData->u64LastReceiveTS, u64Now - pData->u64LastTransferTS));
     280            pData->u64LastReceiveTS = u64Now;
    297281#endif
    298                 Log2(("drvTAPAsyncIoThread: cbRead=%#x\n"
    299                       "%.*Vhxd\n",
    300                       cbRead, cbRead, achBuf));
    301                 STAM_COUNTER_INC(&pData->StatPktRecv);
    302                 STAM_COUNTER_ADD(&pData->StatPktRecvBytes, cbRead);
    303                 rc = pData->pPort->pfnReceive(pData->pPort, achBuf, cbRead);
    304                 AssertRC(rc);
    305             }
    306             else
    307             {
    308                 LogFlow(("drvTAPAsyncIoThread: RTFileRead -> %Vrc\n", rc));
    309                 if (rc == VERR_INVALID_HANDLE)
    310                     break;
    311                 RTThreadYield();
    312             }
    313         }
    314         else if (   rc > 0
    315                  && aFDs[1].revents)
    316         {
    317             LogFlow(("drvTAPAsyncIoThread: Control message: enmState=%d revents=%#x\n", pData->enmState, aFDs[1].revents));
    318             if (pData->enmState == ASYNCSTATE_TERMINATE)
    319                 break;
    320             if (aFDs[1].revents & (POLLHUP | POLLERR | POLLNVAL))
    321                 break;
    322 
    323             /* drain the pipe */
    324             char ch;
    325             unsigned cbRead;
    326             RTFileRead(pData->PipeRead, &ch, 1, &cbRead);
     282            Log2(("drvTAPOs2AsyncIoThread: cbRead=%#x\n"
     283                  "%.*Vhxd\n",
     284                  cbRead, cbRead, achBuf));
     285            STAM_COUNTER_INC(&pData->StatPktRecv);
     286            STAM_COUNTER_ADD(&pData->StatPktRecvBytes, cbRead);
     287            rc = pData->pPort->pfnReceive(pData->pPort, achBuf, cbRead);
     288            AssertRC(rc);
    327289        }
    328290        else
    329291        {
    330             /*
    331              * poll() failed for some reason. Yield to avoid eating too much CPU.
    332              *
    333              * EINTR errors have been seen frequently. They should be harmless, even
    334              * if they are not supposed to occur in our setup.
    335              */
    336             if (errno == EINTR)
    337                 Log(("rc=%d revents=%#x,%#x errno=%p %s\n", rc, aFDs[0].revents, aFDs[1].revents, errno, strerror(errno)));
    338             else
    339                 AssertMsgFailed(("rc=%d revents=%#x,%#x errno=%p %s\n", rc, aFDs[0].revents, aFDs[1].revents, errno, strerror(errno)));
     292            LogFlow(("drvTAPOs2AsyncIoThread: RTFileRead -> %Vrc\n", rc));
     293            if (rc == VERR_INVALID_HANDLE)
     294                break;
    340295            RTThreadYield();
    341296        }
    342297    }
    343298
    344     rc = RTSemEventDestroy(pData->EventOutOfSpace);
    345     AssertRC(rc);
    346 
    347     LogFlow(("drvTAPAsyncIoThread: returns %Vrc\n", VINF_SUCCESS));
     299    LogFlow(("drvTAPOs2AsyncIoThread: returns %Vrc\n", VINF_SUCCESS));
    348300    STAM_PROFILE_ADV_STOP(&pData->StatReceive, a);
    349301    return VINF_SUCCESS;
    350302}
    351 
    352 #else
    353 /**
    354  * Poller callback.
    355  */
    356 static DECLCALLBACK(void) drvTAPPoller(PPDMDRVINS pDrvIns)
    357 {
    358     /* check how much the device/driver can receive now. */
    359     PDRVTAP pData = PDMINS2DATA(pDrvIns, PDRVTAP);
    360     STAM_PROFILE_ADV_START(&pData->StatReceive, a);
    361 
    362     size_t  cbMax = pData->pPort->pfnCanReceive(pData->pPort);
    363     while (cbMax > 0)
    364     {
    365         /* check for data to read */
    366         struct pollfd aFDs[1];
    367         aFDs[0].fd      = pData->FileDevice;
    368         aFDs[0].events  = POLLIN | POLLPRI;
    369         aFDs[0].revents = 0;
    370         if (poll(&aFDs[0], 1, 0) > 0)
    371         {
    372             if (aFDs[0].revents & (POLLIN | POLLPRI))
    373             {
    374                 /* data waiting, read it. */
    375                 char        achBuf[4096];
    376                 unsigned    cbRead = 0;
    377                 int rc = RTFileRead(pData->FileDevice, achBuf, RT_MIN(sizeof(achBuf), cbMax), &cbRead);
    378                 if (VBOX_SUCCESS(rc))
    379                 {
    380                     STAM_COUNTER_INC(&pData->StatPktRecv);
    381                     STAM_COUNTER_ADD(&pData->StatPktRecvBytes, cbRead);
    382 
    383                     /* push it up to guy over us. */
    384                     Log2(("drvTAPPoller: cbRead=%#x\n"
    385                           "%.*Vhxd\n",
    386                           cbRead, cbRead, achBuf));
    387                     rc = pData->pPort->pfnReceive(pData->pPort, achBuf, cbRead);
    388                     AssertRC(rc);
    389                 }
    390                 else
    391                     AssertRC(rc);
    392                 if (VBOX_FAILURE(rc) || !cbRead)
    393                     break;
    394             }
    395             else
    396                 break;
    397         }
    398         else
    399             break;
    400 
    401         cbMax = pData->pPort->pfnCanReceive(pData->pPort);
    402     }
    403 
    404     STAM_PROFILE_ADV_STOP(&pData->StatReceive, a);
    405 }
    406 #endif
    407303
    408304
     
    416312 * @thread  Any thread.
    417313 */
    418 static DECLCALLBACK(void *) drvTAPQueryInterface(PPDMIBASE pInterface, PDMINTERFACE enmInterface)
     314static DECLCALLBACK(void *) drvTAPOs2QueryInterface(PPDMIBASE pInterface, PDMINTERFACE enmInterface)
    419315{
    420316    PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
    421     PDRVTAP pData = PDMINS2DATA(pDrvIns, PDRVTAP);
     317    PDRVTAPOS2 pData = PDMINS2DATA(pDrvIns, PDRVTAPOS2);
    422318    switch (enmInterface)
    423319    {
     
    440336 * @param   pDrvIns     The driver instance data.
    441337 */
    442 static DECLCALLBACK(void) drvTAPDestruct(PPDMDRVINS pDrvIns)
    443 {
    444     LogFlow(("drvTAPDestruct\n"));
    445 #ifdef ASYNC_NET
    446     PDRVTAP pData = PDMINS2DATA(pDrvIns, PDRVTAP);
    447 
    448     /*
    449      * Terminate the Async I/O Thread.
    450      */
    451     ASMAtomicXchgSize(&pData->enmState, ASYNCSTATE_TERMINATE);
    452     if (pData->Thread != NIL_RTTHREAD)
     338static DECLCALLBACK(void) drvTAPOs2Destruct(PPDMDRVINS pDrvIns)
     339{
     340    LogFlow(("drvTAPOs2Destruct\n"));
     341    PDRVTAPOS2 pData = PDMINS2DATA(pDrvIns, PDRVTAPOS2);
     342
     343    /*
     344     * Destroy the event semaphore.
     345     */
     346    if (pData->EventOutOfSpace != NIL_RTSEMEVENTMULTI)
    453347    {
    454         /* Ensure that it does not spin in the CanReceive loop */
    455         if (ASMAtomicXchgU32(&pData->fOutOfSpace, false))
    456             RTSemEventSignal(pData->EventOutOfSpace);
    457 
    458         int rc = RTFileWrite(pData->PipeWrite, "", 1, NULL);
     348        rc = RTSemEventDestroy(pData->EventOutOfSpace);
    459349        AssertRC(rc);
    460         rc = RTThreadWait(pData->Thread, 5000, NULL);
    461         AssertRC(rc);
    462         pData->Thread = NIL_RTTHREAD;
     350        pData->EventOutOfSpace = NIL_RTSEMEVENTMULTI;
    463351    }
    464 
    465     /*
    466      * Terminate the control pipe.
    467      */
    468     if (pData->PipeWrite != NIL_RTFILE)
    469     {
    470         int rc = RTFileClose(pData->PipeWrite);
    471         AssertRC(rc);
    472         pData->PipeWrite = NIL_RTFILE;
    473     }
    474     if (pData->PipeRead != NIL_RTFILE)
    475     {
    476         int rc = RTFileClose(pData->PipeRead);
    477         AssertRC(rc);
    478         pData->PipeRead = NIL_RTFILE;
    479     }
    480 #endif
    481352}
    482353
     
    492363 *                      iInstance it's expected to be used a bit in this function.
    493364 */
    494 static DECLCALLBACK(int) drvTAPConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfgHandle)
    495 {
    496     PDRVTAP pData = PDMINS2DATA(pDrvIns, PDRVTAP);
     365static DECLCALLBACK(int) drvTAPOs2Construct(PPDMDRVINS pDrvIns, PCFGMNODE pCfgHandle)
     366{
     367    PDRVTAPOS2 pData = PDMINS2DATA(pDrvIns, PDRVTAPOS2);
    497368
    498369    /*
     
    501372    pData->pDrvIns                      = pDrvIns;
    502373    pData->FileDevice                   = NIL_RTFILE;
    503 #ifdef ASYNC_NET
    504374    pData->Thread                       = NIL_RTTHREAD;
    505375    pData->enmState                     = ASYNCSTATE_RUNNING;
    506 #endif
    507376    /* IBase */
    508     pDrvIns->IBase.pfnQueryInterface    = drvTAPQueryInterface;
     377    pDrvIns->IBase.pfnQueryInterface    = drvTAPOs2QueryInterface;
    509378    /* INetwork */
    510     pData->INetworkConnector.pfnSend                = drvTAPSend;
    511     pData->INetworkConnector.pfnSetPromiscuousMode  = drvTAPSetPromiscuousMode;
    512     pData->INetworkConnector.pfnNotifyLinkChanged   = drvTAPNotifyLinkChanged;
    513     pData->INetworkConnector.pfnNotifyCanReceive    = drvTAPNotifyCanReceive;
     379    pData->INetworkConnector.pfnSend                = drvTAPOs2Send;
     380    pData->INetworkConnector.pfnSetPromiscuousMode  = drvTAPOs2SetPromiscuousMode;
     381    pData->INetworkConnector.pfnNotifyLinkChanged   = drvTAPOs2NotifyLinkChanged;
     382    pData->INetworkConnector.pfnNotifyCanReceive    = drvTAPOs2NotifyCanReceive;
    514383
    515384    /*
     
    557426        return PDMDrvHlpVMSetError(pDrvIns, VERR_HOSTIF_IOCTL, RT_SRC_POS,
    558427                                   N_("Configuration error: Failed to configure /dev/net/tun. errno=%d"), errno);
    559     /** @todo determine device name. This can be done by reading the link /proc/<pid>/fd/<fd> */
    560     Log(("drvTAPContruct: %d (from fd)\n", pData->FileDevice));
     428    Log(("drvTAPOs2Contruct: %d (from fd)\n", pData->FileDevice));
    561429    rc = VINF_SUCCESS;
    562430
    563 #ifdef ASYNC_NET
    564     /*
    565      * Create the control pipe.
    566      */
    567     int fds[2];
    568     if (pipe(&fds[0]) != 0) /** @todo RTPipeCreate() or something... */
    569     {
    570         int rc = RTErrConvertFromErrno(errno);
    571         AssertRC(rc);
    572         return rc;
    573     }
    574     pData->PipeRead = fds[0];
    575     pData->PipeWrite = fds[1];
    576 
    577     /*
    578      * Create the async I/O thread.
    579      */
    580     rc = RTThreadCreate(&pData->Thread, drvTAPAsyncIoThread, pData, 128*_1K, RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "TAP");
     431    /*
     432     * Create the out-of-space semaphore and the async receiver thread.
     433     */
     434    rc = RTSemEventCreate(&pData->EventOutOfSpace);
    581435    AssertRCReturn(rc, rc);
    582 #else
    583     /*
    584      * Register poller
    585      */
    586     rc = pDrvIns->pDrvHlp->pfnPDMPollerRegister(pDrvIns, drvTAPPoller);
     436
     437    rc = PDMDrvHlpThreadCreate(pDrvIns, &pData->pThread, pData, drvTAPOs2AsyncIoThread, drvTAPOs2WakeupThread,
     438                               0, RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "TAP");
    587439    AssertRCReturn(rc, rc);
    588 #endif
    589440
    590441#ifdef VBOX_WITH_STATISTICS
     
    598449    PDMDrvHlpSTAMRegisterF(pDrvIns, &pData->StatTransmit,      STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL,    "Profiling packet transmit runs.",  "/Drivers/TAP%d/Transmit", pDrvIns->iInstance);
    599450    PDMDrvHlpSTAMRegisterF(pDrvIns, &pData->StatReceive,       STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL,    "Profiling packet receive runs.",   "/Drivers/TAP%d/Receive", pDrvIns->iInstance);
    600 # ifdef ASYNC_NET
    601451    PDMDrvHlpSTAMRegisterF(pDrvIns, &pData->StatRecvOverflows, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_OCCURENCE, "Profiling packet receive overflows.", "/Drivers/TAP%d/RecvOverflows", pDrvIns->iInstance);
    602 # endif
    603452#endif /* VBOX_WITH_STATISTICS */
    604453
     
    625474    ~0,
    626475    /* cbInstance */
    627     sizeof(DRVTAP),
     476    sizeof(DRVTAPOS2),
    628477    /* pfnConstruct */
    629     drvTAPConstruct,
     478    drvTAPOs2Construct,
    630479    /* pfnDestruct */
    631     drvTAPDestruct,
     480    drvTAPOs2Destruct,
    632481    /* pfnIOCtl */
    633482    NULL,
     
    637486    NULL,
    638487    /* pfnSuspend */
    639     NULL, /** @todo Do power on, suspend and resume handlers! */
     488    NULL,
    640489    /* pfnResume */
    641490    NULL,
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