VirtualBox

Changeset 50321 in vbox


Ignore:
Timestamp:
Feb 5, 2014 8:30:46 AM (11 years ago)
Author:
vboxsync
Message:

Mac OS X host: prevent stuck-in-dock: r91968 is substituted with the new solution: send dummy packet in a context of a kernel thread in order to associate interface's receive thread w/ our new kernel thread instead of VirtualBoxVM process.

Location:
trunk
Files:
1 added
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/VBoxNetAdp/darwin/VBoxNetAdp-darwin.cpp

    r49686 r50321  
    3232#include <VBox/err.h>
    3333#include <VBox/version.h>
     34#include <VBox/VBoxNetSend.h>
    3435#include <iprt/assert.h>
    3536#include <iprt/initterm.h>
     
    233234}
    234235
    235 
    236 /**
    237  * Constructs and submits a dummy packet to ifnet_input(). This is a workaround
    238  * for "stuck dock icon" issue. When the first packet goes through the interface
    239  * DLIL grabs a reference to the thread that submits the packet and holds it
    240  * until the interface is destroyed. By submitting this dummy we make DLIL grab
    241  * the thread of a non-GUI process.
    242  *
    243  * Most of this function was copied from vboxNetFltDarwinMBufFromSG().
    244  *
    245  * @returns VBox status code.
    246  * @param   pIfNet      The interface that will hold the reference to the calling
    247  *                      thread. We submit dummy as if it was coming from this interface.
    248  */
    249 static int vboxNetSendDummy(ifnet_t pIfNet)
    250 {
    251     int rc = 0;
    252     size_t cbTotal = 50; /* No Ethernet header */
    253     mbuf_how_t How = MBUF_WAITOK;
    254 
    255     mbuf_t pPkt = NULL;
    256     errno_t err = mbuf_allocpacket(How, cbTotal, NULL, &pPkt);
    257     if (!err)
    258     {
    259         /* Skip zero sized memory buffers (paranoia). */
    260         mbuf_t pCur = pPkt;
    261         while (pCur && !mbuf_maxlen(pCur))
    262             pCur = mbuf_next(pCur);
    263         Assert(pCur);
    264 
    265         /* Set the required packet header attributes. */
    266         mbuf_pkthdr_setlen(pPkt, cbTotal);
    267         mbuf_pkthdr_setheader(pPkt, mbuf_data(pCur));
    268 
    269         mbuf_setlen(pCur, cbTotal);
    270         memset(mbuf_data(pCur), 0, cbTotal);
    271 
    272         mbuf_pkthdr_setrcvif(pPkt, pIfNet); /* will crash without this. */
    273 
    274         errno_t err = ifnet_input(pIfNet, pPkt, NULL);
    275         if (err)
    276         {
    277             rc = RTErrConvertFromErrno(err);
    278             mbuf_freem(pPkt);
    279         }
    280     }
    281     else
    282         rc = RTErrConvertFromErrno(err);
    283 
    284     return rc;
    285 }
    286236
    287237int vboxNetAdpOsCreate(PVBOXNETADP pThis, PCRTMAC pMACAddress)
     
    347297            {
    348298                ifnet_set_mtu(pThis->u.s.pIface, VBOXNETADP_MTU);
    349                 vboxNetSendDummy(pThis->u.s.pIface);
     299                VboxNetSendDummy(pThis->u.s.pIface);
    350300                return VINF_SUCCESS;
    351301            }
  • trunk/src/VBox/HostDrivers/VBoxNetFlt/darwin/VBoxNetFlt-darwin.cpp

    r50298 r50321  
    3535#include <VBox/intnetinline.h>
    3636#include <VBox/version.h>
     37#include <VBox/VBoxNetSend.h>
    3738#include <iprt/initterm.h>
    3839#include <iprt/assert.h>
     
    4445#include <iprt/time.h>
    4546#include <iprt/net.h>
     47#include <iprt/thread.h>
    4648
    4749#include <mach/kmod.h>
     
    883885
    884886
     887/** A worker for vboxNetFltSendDummy() thread. */
     888static int vboxNetFltSendDummyWorker(RTTHREAD ThreadSelf, void *pvUser)
     889{
     890    Assert(pvUser);
     891    ifnet_t pIfNet = (ifnet_t)pvUser;
     892    return VboxNetSendDummy(pIfNet);
     893}
     894
     895/*
     896 * Prevent GUI icon freeze issue when VirtualBoxVM process terminates.
     897 *
     898 * This function is a workaround for stuck-in-dock issue. The
     899 * idea here is to send a dummy packet to an interface from the
     900 * context of a kernel thread. Therefore, an XNU's receive
     901 * thread (which is created as a result if we are the first who
     902 * is communicating with the interface) will be associated with the
     903 * kernel thread instead of VirtualBoxVM process.
     904 *
     905 * @param pIfNet    Interface to be used to send data.
     906 */
     907static void vboxNetFltSendDummy(ifnet_t pIfNet)
     908{
     909    RTTHREAD dummyThread;
     910    int rc;
     911
     912    rc = RTThreadCreate(&dummyThread, vboxNetFltSendDummyWorker, (void *)pIfNet, 0,
     913        RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "DummyThread");
     914
     915    if (RT_SUCCESS(rc))
     916    {
     917        RTThreadWait(dummyThread, RT_INDEFINITE_WAIT, NULL);
     918        LogFlow(("vboxNetFltSendDummy: a dummy packet has been successfully sent in order to prevent stuck-in-dock issue\n"));
     919    }
     920    else
     921        LogFlow(("vboxNetFltSendDummy: unable to send dummy packet in order to prevent stuck-in-dock issue\n"));
     922}
     923
    885924/**
    886925 * Internal worker for vboxNetFltOsInitInstance and vboxNetFltOsMaybeRediscovered.
     
    917956    ASMAtomicUoWritePtr(&pThis->u.s.pIfNet, pIfNet);
    918957    RTSpinlockReleaseNoInts(pThis->hSpinlock);
     958
     959    /* Prevent stuck-in-dock issue by associating interface receive thread with kernel thread */
     960    vboxNetFltSendDummy(pIfNet);
    919961
    920962    /*
     
    9831025
    9841026
    985 /**
    986  * Attempt to detect if a cable is attached to a network card.
    987  * There is no direct way to detect this at any time. We assume
    988  * if interface's baud rate is not zero then cable is attached.
    989  */
    990 static int vboxNetFltCableAttached(ifnet_t pIfNet)
    991 {
    992     return (ifnet_baudrate(pIfNet) != 0);
    993 }
    994 
    995 
    9961027int  vboxNetFltPortOsXmit(PVBOXNETFLTINS pThis, void *pvIfData, PINTNETSG pSG, uint32_t fDst)
    9971028{
     
    10021033    if (pIfNet)
    10031034    {
    1004         /*
    1005          * Do not send any data to a network stack if cable is not attached
    1006          * to a network card device in order to prevent stuck-in-dock problem. */
    1007         if (!vboxNetFltCableAttached(pIfNet))
    1008         {
    1009             vboxNetFltDarwinReleaseIfNet(pThis, pIfNet);
    1010             return rc;
    1011         }
    1012 
    10131035        /*
    10141036         * Create a mbuf for the gather list and push it onto the wire.
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