Changeset 50321 in vbox
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostDrivers/VBoxNetAdp/darwin/VBoxNetAdp-darwin.cpp
r49686 r50321 32 32 #include <VBox/err.h> 33 33 #include <VBox/version.h> 34 #include <VBox/VBoxNetSend.h> 34 35 #include <iprt/assert.h> 35 36 #include <iprt/initterm.h> … … 233 234 } 234 235 235 236 /**237 * Constructs and submits a dummy packet to ifnet_input(). This is a workaround238 * for "stuck dock icon" issue. When the first packet goes through the interface239 * DLIL grabs a reference to the thread that submits the packet and holds it240 * until the interface is destroyed. By submitting this dummy we make DLIL grab241 * 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 calling247 * 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 else282 rc = RTErrConvertFromErrno(err);283 284 return rc;285 }286 236 287 237 int vboxNetAdpOsCreate(PVBOXNETADP pThis, PCRTMAC pMACAddress) … … 347 297 { 348 298 ifnet_set_mtu(pThis->u.s.pIface, VBOXNETADP_MTU); 349 vboxNetSendDummy(pThis->u.s.pIface);299 VboxNetSendDummy(pThis->u.s.pIface); 350 300 return VINF_SUCCESS; 351 301 } -
trunk/src/VBox/HostDrivers/VBoxNetFlt/darwin/VBoxNetFlt-darwin.cpp
r50298 r50321 35 35 #include <VBox/intnetinline.h> 36 36 #include <VBox/version.h> 37 #include <VBox/VBoxNetSend.h> 37 38 #include <iprt/initterm.h> 38 39 #include <iprt/assert.h> … … 44 45 #include <iprt/time.h> 45 46 #include <iprt/net.h> 47 #include <iprt/thread.h> 46 48 47 49 #include <mach/kmod.h> … … 883 885 884 886 887 /** A worker for vboxNetFltSendDummy() thread. */ 888 static 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 */ 907 static 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 885 924 /** 886 925 * Internal worker for vboxNetFltOsInitInstance and vboxNetFltOsMaybeRediscovered. … … 917 956 ASMAtomicUoWritePtr(&pThis->u.s.pIfNet, pIfNet); 918 957 RTSpinlockReleaseNoInts(pThis->hSpinlock); 958 959 /* Prevent stuck-in-dock issue by associating interface receive thread with kernel thread */ 960 vboxNetFltSendDummy(pIfNet); 919 961 920 962 /* … … 983 1025 984 1026 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 assume988 * 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 996 1027 int vboxNetFltPortOsXmit(PVBOXNETFLTINS pThis, void *pvIfData, PINTNETSG pSG, uint32_t fDst) 997 1028 { … … 1002 1033 if (pIfNet) 1003 1034 { 1004 /*1005 * Do not send any data to a network stack if cable is not attached1006 * 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 1013 1035 /* 1014 1036 * Create a mbuf for the gather list and push it onto the wire.
Note:
See TracChangeset
for help on using the changeset viewer.