VirtualBox

Changeset 97338 in vbox for trunk


Ignore:
Timestamp:
Oct 31, 2022 8:15:38 AM (2 years ago)
Author:
vboxsync
Message:

NetworkServices/IntNetSwitch,Devices/Network/DrvIntNet,Devices/Network/SrvIntNetR0: Don't require a dedicated waiting thread to get notified when there is something to receive but make it possible to register a callback which is called and sends an IPC message instead, bugref:10297

Location:
trunk
Files:
5 edited
1 moved

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/intnet.h

    r97046 r97338  
    5151/** The userspace internal network service identifier. */
    5252#if defined(RT_OS_DARWIN) && defined(VBOX_WITH_INTNET_SERVICE_IN_R3)
    53 # define INTNET_R3_SVC_NAME "org.virtualbox.intnet"
     53/** The XPC service identififer. */
     54# define INTNET_R3_SVC_NAME                 "org.virtualbox.intnet"
     55/** The high 32 bits pattern for the "rc" status code field to recognize errors
     56 * where xpc_dictionary_get_int64() might return 0 which could be confused with VINF_SUCCESS. */
     57# define INTNET_R3_SVC_RC_PATTERN           ((uint64_t)RT_MAKE_U32_FROM_U8('V', 'B', 'O', 'X'))
     58/** Constructs a signd 64bit value for the given 32-bit status code. */
     59# define INTNET_R3_SVC_SET_RC(a_rc)         ((INTNET_R3_SVC_RC_PATTERN << 32) | (uint64_t)(a_rc))
     60/** Gets the status code from the given 64-bit signed status code value. */
     61# define INTNET_R3_SVC_GET_RC(a_RcVal)      ((int32_t)(a_RcVal))
     62/** Checks whether the given 64-bit signed status code value encodes a valid IPRT/VBOX status code. */
     63# define INTNET_R3_SVC_IS_VALID_RC(a_RcVal) (((a_RcVal) >> 32) == INTNET_R3_SVC_RC_PATTERN)
    5464#endif
    5565
     
    13171327#endif /* IN_RING0 */
    13181328
     1329/**
     1330 * Callback function for use with IntNetR3Open to signalling incoming data.
     1331 * 
     1332 * @param   hIf     Interface handle.
     1333 * @param   pvUser  User parameter.
     1334 */
     1335typedef DECLCALLBACKTYPE(void, FNINTNETIFRECVAVAIL,(INTNETIFHANDLE hIf, void *pvUser));
     1336/** Pointer to a FNINTNETIFRECVAVAIL callback. */
     1337typedef FNINTNETIFRECVAVAIL *PFNINTNETIFRECVAVAIL;
     1338
     1339#if defined(VBOX_WITH_INTNET_SERVICE_IN_R3) && defined(IN_RING3)
     1340INTNETR3DECL(int)       IntNetR3Open(PSUPDRVSESSION pSession, const char *pszNetwork,
     1341                                     INTNETTRUNKTYPE enmTrunkType, const char *pszTrunk, uint32_t fFlags,
     1342                                     uint32_t cbSend, uint32_t cbRecv, PFNINTNETIFRECVAVAIL pfnRecvAvail,
     1343                                     void *pvUserRecvAvail, PINTNETIFHANDLE phIf);
     1344#endif
     1345
    13191346RT_C_DECLS_END
    13201347
  • trunk/src/VBox/Devices/Network/DrvIntNet.cpp

    r97089 r97338  
    249249        xpc_dictionary_set_data(hObj, "req", pvArg, cbArg);
    250250        xpc_object_t hObjReply = xpc_connection_send_message_with_reply_sync(pThis->hXpcCon, hObj);
    251         int rc = (int)xpc_dictionary_get_int64(hObjReply, "rc");
    252 
    253         size_t cbReply = 0;
    254         const void *pvData = xpc_dictionary_get_data(hObjReply, "reply", &cbReply);
    255         AssertRelease(cbReply == cbArg);
    256         memcpy(pvArg, pvData, cbArg);
     251        uint64_t u64Rc = xpc_dictionary_get_uint64(hObjReply, "rc");
     252        if (INTNET_R3_SVC_IS_VALID_RC(u64Rc))
     253        {
     254            size_t cbReply = 0;
     255            const void *pvData = xpc_dictionary_get_data(hObjReply, "reply", &cbReply);
     256            AssertRelease(cbReply == cbArg);
     257            memcpy(pvArg, pvData, cbArg);
     258            xpc_release(hObjReply);
     259
     260            return INTNET_R3_SVC_GET_RC(u64Rc);
     261        }
     262
    257263        xpc_release(hObjReply);
    258 
    259         return rc;
     264        return VERR_INVALID_STATE;
    260265    }
    261266    else
     
    316321        xpc_dictionary_set_data(hObj, "req", &GetBufferPtrsReq, sizeof(GetBufferPtrsReq));
    317322        xpc_object_t hObjReply = xpc_connection_send_message_with_reply_sync(pThis->hXpcCon, hObj);
    318         rc = (int)xpc_dictionary_get_int64(hObjReply, "rc");
     323        uint64_t u64Rc = xpc_dictionary_get_uint64(hObjReply, "rc");
     324        if (INTNET_R3_SVC_IS_VALID_RC(u64Rc))
     325            rc = INTNET_R3_SVC_GET_RC(u64Rc);
     326        else
     327            rc = VERR_INVALID_STATE;
     328
    319329        if (RT_SUCCESS(rc))
    320330        {
     
    327337                pThis->cbBuf = cbMem;
    328338        }
     339
    329340        xpc_release(hObjReply);
    330341    }
  • trunk/src/VBox/Devices/Network/SrvIntNetR0.cpp

    r96407 r97338  
    245245    /** Pointer to ring-3 mapping of the default exchange buffer. */
    246246    R3PTRTYPE(PINTNETBUF)   pIntBufDefaultR3;
     247#if !defined(VBOX_WITH_INTNET_SERVICE_IN_R3) || !defined(IN_RING3)
    247248    /** Event semaphore which a receiver/consumer thread will sleep on while
    248249     * waiting for data to arrive. */
     
    250251    /** Number of threads sleeping on the event semaphore. */
    251252    uint32_t volatile       cSleepers;
     253#else
     254    /** The callback to call when there is something to receive/consume. */
     255    PFNINTNETIFRECVAVAIL    pfnRecvAvail;
     256    /** Opaque user data to pass to the receive avail callback (pfnRecvAvail). */
     257    void                   *pvUserRecvAvail;
     258#endif
    252259    /** The interface handle.
    253260     * When this is INTNET_HANDLE_INVALID a sleeper which is waking up
     
    28332840
    28342841
     2842/**
     2843 * Notifies consumers of incoming data from @a pIf that data is available.
     2844 */
     2845DECL_FORCE_INLINE(void) intnetR0IfNotifyRecv(PINTNETIF pIf)
     2846{
     2847#if !defined(VBOX_WITH_INTNET_SERVICE_IN_R3) || !defined(IN_RING3)
     2848    RTSemEventSignal(pIf->hRecvEvent);
     2849#else
     2850    pIf->pfnRecvAvail(pIf->hIf, pIf->pvUserRecvAvail);
     2851#endif
     2852}
     2853
     2854
    28352855/**
    28362856 * Sends a frame to a specific interface.
     
    28522872    {
    28532873        pIf->cYields = 0;
    2854         RTSemEventSignal(pIf->hRecvEvent);
     2874        intnetR0IfNotifyRecv(pIf);
    28552875        return;
    28562876    }
     
    28702890        while (--cYields > 0)
    28712891        {
    2872             RTSemEventSignal(pIf->hRecvEvent);
     2892            intnetR0IfNotifyRecv(pIf);
    28732893            RTThreadYield();
    28742894
     
    28792899            {
    28802900                STAM_REL_COUNTER_INC(&pIf->pIntBuf->cStatYieldsOk);
    2881                 RTSemEventSignal(pIf->hRecvEvent);
     2901                intnetR0IfNotifyRecv(pIf);
    28822902                return;
    28832903            }
     
    28892909    /* ok, the frame is lost. */
    28902910    STAM_REL_COUNTER_INC(&pIf->pIntBuf->cStatLost);
    2891     RTSemEventSignal(pIf->hRecvEvent);
     2911    intnetR0IfNotifyRecv(pIf);
    28922912}
    28932913
     
    46674687    }
    46684688
    4669     const RTSEMEVENT hRecvEvent   = pIf->hRecvEvent;
     4689#if defined(VBOX_WITH_INTNET_SERVICE_IN_R3) && defined(IN_RING3)
     4690    AssertReleaseFailed(); /* Should never be called. */
     4691    return VERR_NOT_SUPPORTED;
     4692#else
     4693    const RTSEMEVENT hRecvEvent  = pIf->hRecvEvent;
    46704694    const bool       fNoMoreWaits = ASMAtomicUoReadBool(&pIf->fNoMoreWaits);
    46714695    RTNATIVETHREAD   hDtorThrd;
     
    47214745    Log4(("IntNetR0IfWait: returns %Rrc\n", rc));
    47224746    return rc;
     4747#endif
    47234748}
    47244749
     
    47654790    }
    47664791
     4792#if defined(VBOX_WITH_INTNET_SERVICE_IN_R3) && defined(IN_RING3)
     4793    AssertReleaseFailed();
     4794    return VERR_NOT_SUPPORTED;
     4795#else
    47674796    const RTSEMEVENT hRecvEvent  = pIf->hRecvEvent;
    47684797    RTNATIVETHREAD   hDtorThrd;
     
    48074836    Log4(("IntNetR0IfWait: returns %Rrc\n", VINF_SUCCESS));
    48084837    return VINF_SUCCESS;
     4838#endif
    48094839}
    48104840
     
    48514881    ASMAtomicWriteU32(&pIf->hIf, INTNET_HANDLE_INVALID);
    48524882
     4883#if !defined(VBOX_WITH_INTNET_SERVICE_IN_R3) || !defined(IN_RING3)
    48534884    /*
    48544885     * Signal the event semaphore to wake up any threads in IntNetR0IfWait
     
    48624893    }
    48634894    RTSemEventSignal(pIf->hRecvEvent);
     4895#endif
    48644896
    48654897    /*
     
    50005032    RTSemMutexRelease(pIntNet->hMtxCreateOpenDestroy);
    50015033
     5034#if !defined(VBOX_WITH_INTNET_SERVICE_IN_R3) || !defined(IN_RING3)
    50025035    /*
    50035036     * Wakeup anyone waiting on this interface. (Kind of unlikely, but perhaps
     
    50315064        pIf->hRecvEvent = NIL_RTSEMEVENT;
    50325065    }
     5066#endif
    50335067
    50345068    /*
     
    50805114 *
    50815115 * @returns VBox status code.
    5082  * @param   pNetwork    The network, referenced.  The reference is consumed on
    5083  *                      success.
    5084  * @param   pSession    The session handle.
    5085  * @param   cbSend      The size of the send buffer.
    5086  * @param   cbRecv      The size of the receive buffer.
    5087  * @param   fFlags      The open network flags.
    5088  * @param   phIf        Where to store the interface handle.
    5089  */
    5090 static int intnetR0NetworkCreateIf(PINTNETNETWORK pNetwork, PSUPDRVSESSION pSession,
    5091                                    unsigned cbSend, unsigned cbRecv, uint32_t fFlags,
    5092                                    PINTNETIFHANDLE phIf)
     5116 * @param   pNetwork        The network, referenced.  The reference is consumed
     5117 *                          on success.
     5118 * @param   pSession        The session handle.
     5119 * @param   cbSend          The size of the send buffer.
     5120 * @param   cbRecv          The size of the receive buffer.
     5121 * @param   fFlags          The open network flags.
     5122 * @param   pfnRecvAvail    The receive available callback to call instead of
     5123 *                          signalling the semaphore (R3 service only).
     5124 * @param   pvUser          The opaque user data to pass to the callback.
     5125 * @param   phIf            Where to store the interface handle.
     5126 */
     5127static int intnetR0NetworkCreateIf(PINTNETNETWORK pNetwork, PSUPDRVSESSION pSession, unsigned cbSend, unsigned cbRecv,
     5128                                   uint32_t fFlags, PFNINTNETIFRECVAVAIL pfnRecvAvail, void *pvUser, PINTNETIFHANDLE phIf)
    50935129{
    50945130    LogFlow(("intnetR0NetworkCreateIf: pNetwork=%p pSession=%p cbSend=%u cbRecv=%u fFlags=%#x phIf=%p\n",
     
    51005136    AssertPtr(pNetwork);
    51015137    AssertPtr(phIf);
     5138#if !defined(VBOX_WITH_INTNET_SERVICE_IN_R3) || !defined(IN_RING3)
     5139    Assert(pfnRecvAvail == NULL);
     5140    Assert(pvUser == NULL);
     5141    RT_NOREF(pfnRecvAvail, pvUser);
     5142#endif
    51025143
    51035144    /*
     
    51365177    //pIf->pIntBufDefault   = 0;
    51375178    //pIf->pIntBufDefaultR3 = NIL_RTR3PTR;
     5179#if !defined(VBOX_WITH_INTNET_SERVICE_IN_R3) || !defined(IN_RING3)
    51385180    pIf->hRecvEvent         = NIL_RTSEMEVENT;
     5181#else
     5182    pIf->pfnRecvAvail       = pfnRecvAvail;
     5183    pIf->pvUserRecvAvail    = pvUser;
     5184#endif
    51395185    //pIf->cSleepers        = 0;
    51405186    pIf->hIf                = INTNET_HANDLE_INVALID;
     
    51545200    if (RT_SUCCESS(rc))
    51555201        rc = intnetR0AllocDstTab(pNetwork->MacTab.cEntriesAllocated, (PINTNETDSTTAB *)&pIf->pDstTab);
     5202#if !defined(VBOX_WITH_INTNET_SERVICE_IN_R3) || !defined(IN_RING3)
    51565203    if (RT_SUCCESS(rc))
    51575204        rc = RTSemEventCreate((PRTSEMEVENT)&pIf->hRecvEvent);
     5205#endif
    51585206    if (RT_SUCCESS(rc))
    51595207        rc = RTSpinlockCreate(&pIf->hRecvInSpinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "hRecvInSpinlock");
     
    52485296    RTSpinlockDestroy(pIf->hRecvInSpinlock);
    52495297    pIf->hRecvInSpinlock = NIL_RTSPINLOCK;
     5298#if !defined(VBOX_WITH_INTNET_SERVICE_IN_R3) || !defined(IN_RING3)
    52505299    RTSemEventDestroy(pIf->hRecvEvent);
    52515300    pIf->hRecvEvent = NIL_RTSEMEVENT;
     5301#else
     5302    pIf->pfnRecvAvail    = NULL;
     5303    pIf->pvUserRecvAvail = NULL;
     5304#endif
    52525305    RTMemFree(pIf->pDstTab);
    52535306    for (int i = kIntNetAddrType_Invalid + 1; i < kIntNetAddrType_End; i++)
     
    65946647 * @param   pszTrunk        The trunk name. Its meaning is specific to the type.
    65956648 * @param   fFlags          Flags, see INTNET_OPEN_FLAGS_*.
    6596  * @param   fRestrictAccess Whether new participants should be subjected to access check or not.
     6649 * @param   fRestrictAccess Whether new participants should be subjected to
     6650 *                          access check or not.
    65976651 * @param   cbSend          The send buffer size.
    65986652 * @param   cbRecv          The receive buffer size.
     6653 * @param   pfnRecvAvail    The receive available callback to call instead of
     6654 *                          signalling the semaphore (R3 service only).
     6655 * @param   pvUser          The opaque user data to pass to the callback.
    65996656 * @param   phIf            Where to store the handle to the network interface.
    66006657 */
    66016658INTNETR0DECL(int) IntNetR0Open(PSUPDRVSESSION pSession, const char *pszNetwork,
    66026659                               INTNETTRUNKTYPE enmTrunkType, const char *pszTrunk, uint32_t fFlags,
    6603                                uint32_t cbSend, uint32_t cbRecv, PINTNETIFHANDLE phIf)
     6660                               uint32_t cbSend, uint32_t cbRecv, PFNINTNETIFRECVAVAIL pfnRecvAvail, void *pvUser,
     6661                               PINTNETIFHANDLE phIf)
    66046662{
    66056663    LogFlow(("IntNetR0Open: pSession=%p pszNetwork=%p:{%s} enmTrunkType=%d pszTrunk=%p:{%s} fFlags=%#x cbSend=%u cbRecv=%u phIf=%p\n",
     
    66756733    if (RT_SUCCESS(rc))
    66766734    {
    6677         rc = intnetR0NetworkCreateIf(pNetwork, pSession, cbSend, cbRecv, fFlags, phIf);
     6735        rc = intnetR0NetworkCreateIf(pNetwork, pSession, cbSend, cbRecv, fFlags, pfnRecvAvail, pvUser, phIf);
    66786736        if (RT_SUCCESS(rc))
    66796737        {
     
    66896747        if (RT_SUCCESS(rc))
    66906748        {
    6691             rc = intnetR0NetworkCreateIf(pNetwork, pSession, cbSend, cbRecv, fFlags, phIf);
     6749            rc = intnetR0NetworkCreateIf(pNetwork, pSession, cbSend, cbRecv, fFlags, pfnRecvAvail, pvUser, phIf);
    66926750            if (RT_FAILURE(rc))
    66936751                SUPR0ObjRelease(pNetwork->pvObj, pSession);
     
    67136771        return VERR_INVALID_PARAMETER;
    67146772    return IntNetR0Open(pSession, &pReq->szNetwork[0], pReq->enmTrunkType, pReq->szTrunk,
    6715                         pReq->fFlags, pReq->cbSend, pReq->cbRecv, &pReq->hIf);
    6716 }
     6773                        pReq->fFlags, pReq->cbSend, pReq->cbRecv, NULL /*pfnRecvAvail*/, NULL /*pvUser*/, &pReq->hIf);
     6774}
     6775
     6776
     6777#if defined(VBOX_WITH_INTNET_SERVICE_IN_R3) && defined(IN_RING3)
     6778INTNETR3DECL(int) IntNetR3Open(PSUPDRVSESSION pSession, const char *pszNetwork,
     6779                               INTNETTRUNKTYPE enmTrunkType, const char *pszTrunk, uint32_t fFlags,
     6780                               uint32_t cbSend, uint32_t cbRecv, PFNINTNETIFRECVAVAIL pfnRecvAvail, void *pvUser,
     6781                               PINTNETIFHANDLE phIf)
     6782{
     6783    return IntNetR0Open(pSession, pszNetwork, enmTrunkType, pszTrunk, fFlags, cbSend, cbRecv, pfnRecvAvail, pvUser, phIf);
     6784}
     6785#endif
    67176786
    67186787
  • trunk/src/VBox/Devices/Network/testcase/tstIntNetR0.cpp

    r97300 r97338  
    447447{
    448448    pThis->hIf0 = INTNET_HANDLE_INVALID;
    449     RTTESTI_CHECK_RC_OK_RET(IntNetR0Open(g_pSession, pszNetwork, kIntNetTrunkType_None, "",
    450                                          0/*fFlags*/, cbSend, cbRecv, &pThis->hIf0), rcCheck);
     449    RTTESTI_CHECK_RC_OK_RET(IntNetR0Open(g_pSession, pszNetwork, kIntNetTrunkType_None, "", 0/*fFlags*/, cbSend, cbRecv,
     450                                         NULL /*pfnRecvAvail*/, NULL /*pvUser*/, &pThis->hIf0), rcCheck);
    451451    RTTESTI_CHECK_RET(pThis->hIf0 != INTNET_HANDLE_INVALID, VERR_INTERNAL_ERROR);
    452452    RTTESTI_CHECK_RC_RET(IntNetR0IfGetBufferPtrs(pThis->hIf0, g_pSession, &pThis->pBuf0, NULL), VINF_SUCCESS, rcCheck);
     
    455455
    456456    pThis->hIf1 = INTNET_HANDLE_INVALID;
    457     RTTESTI_CHECK_RC_OK_RET(IntNetR0Open(g_pSession, pszNetwork, kIntNetTrunkType_None, "",
    458                                          0/*fFlags*/, cbSend, cbRecv, &pThis->hIf1), rcCheck);
     457    RTTESTI_CHECK_RC_OK_RET(IntNetR0Open(g_pSession, pszNetwork, kIntNetTrunkType_None, "", 0/*fFlags*/, cbSend, cbRecv,
     458                                         NULL /*pfnRecvAvail*/, NULL /*pvUser*/, &pThis->hIf1), rcCheck);
    459459    RTTESTI_CHECK_RET(pThis->hIf1 != INTNET_HANDLE_INVALID, VERR_INTERNAL_ERROR);
    460460    RTTESTI_CHECK_RC_RET(IntNetR0IfGetBufferPtrs(pThis->hIf1, g_pSession, &pThis->pBuf1, NULL), VINF_SUCCESS, rcCheck);
  • trunk/src/VBox/NetworkServices/IntNetSwitch/Makefile.kmk

    r97122 r97338  
    4040VBoxIntNetSwitch_DEFS      = KBUILD_TYPE=\"$(KBUILD_TYPE)\"
    4141endif
     42VBoxIntNetSwitch_DEFS     += VBOX_WITH_INTNET_SERVICE_IN_R3
    4243VBoxIntNetSwitch_INST.darwin = $(VBoxIntNetSwitch.xpc_INST)/MacOS/
    4344VBoxIntNetSwitch_SOURCES = \
    44         main.cpp \
     45        VBoxIntNetSwitch.cpp \
    4546        SrvIntNetWrapper.cpp
    4647VBoxIntNetSwitch_LIBS = $(LIB_RUNTIME)
  • trunk/src/VBox/NetworkServices/IntNetSwitch/VBoxIntNetSwitch.cpp

    r97337 r97338  
    5353
    5454/*********************************************************************************************************************************
     55*   Defined Constants And Macros                                                                                                 *
     56*********************************************************************************************************************************/
     57
     58
     59/*********************************************************************************************************************************
    5560*   Structures and Typedefs                                                                                                      *
    5661*********************************************************************************************************************************/
     
    116121    /** The XPC connection handle for this session. */
    117122    xpc_connection_t                hXpcCon;
    118     /** The receive wait thread. */
    119     RTTHREAD                        hThrdRecv;
    120123    /** The intnet interface handle to wait on. */
    121124    INTNETIFHANDLE                  hIfWait;
    122     /** The event semaphore for the receive thread. */
    123     RTSEMEVENT                      hEvtRecv;
    124     /** Flag whether to terminate the receive thread. */
    125     bool volatile                   fTerminate;
     125    /** Flag whether a receive wait was initiated. */
     126    bool volatile                   fRecvWait;
     127    /** Flag whether there is something to receive. */
     128    bool volatile                   fRecvAvail;
    126129} SUPDRVSESSION;
    127130
     
    357360    PSUPDRVDEVEXT pDevExt = pSession->pDevExt;
    358361    uint32_t cRefs = ASMAtomicDecU32(&pDevExt->cRefs);
     362    xpc_transaction_end();
    359363    xpc_connection_set_context(pSession->hXpcCon, NULL);
    360364    xpc_connection_cancel(pSession->hXpcCon);
    361365    pSession->hXpcCon = NULL;
    362     xpc_transaction_end();
    363 
    364     /* Tear down the receive wait thread. */
    365     ASMAtomicXchgBool(&pSession->fTerminate, true);
    366     RTSemEventSignal(pSession->hEvtRecv);
    367 
    368     if (pSession->hThrdRecv != NIL_RTTHREAD)
    369     {
    370         int rc = RTThreadWait(pSession->hThrdRecv, 5000, NULL);
    371         AssertRC(rc);
    372         pSession->hThrdRecv = NIL_RTTHREAD;
    373     }
    374 
    375     RTSemEventDestroy(pSession->hEvtRecv);
    376     pSession->hEvtRecv = NIL_RTSEMEVENT;
     366
     367    ASMAtomicXchgBool(&pSession->fRecvAvail, true);
    377368
    378369    if (pSession->pUsage)
     
    422413
    423414        RTCritSectLeave(&pDevExt->CritSect);
    424         AssertMsg(!pSession->pUsage, ("Some buster reregistered an object during desturction!\n"));
     415        AssertMsg(!pSession->pUsage, ("Some buster reregistered an object during destruction!\n"));
    425416    }
    426417
     
    431422
    432423/**
    433  * Asynchronous I/O thread for handling receive.
    434  *
    435  * @returns VINF_SUCCESS (ignored).
    436  * @param   hThreadSelf     Thread handle.
    437  * @param   pvUser          Pointer to a DRVINTNET structure.
    438  */
    439 static DECLCALLBACK(int) intnetR3RecvThread(RTTHREAD hThreadSelf, void *pvUser)
    440 {
    441     RT_NOREF(hThreadSelf);
     424 * Data available in th receive buffer callback.
     425 */
     426static DECLCALLBACK(void) intnetR3RecvAvail(INTNETIFHANDLE hIf, void *pvUser)
     427{
     428    RT_NOREF(hIf);
    442429    PSUPDRVSESSION pSession = (PSUPDRVSESSION)pvUser;
    443430
    444     for (;;)
    445     {
    446         if (pSession->fTerminate)
    447             break;
    448 
    449         RTSemEventWait(pSession->hEvtRecv, RT_INDEFINITE_WAIT);
    450         if (pSession->fTerminate)
    451             break;
    452 
    453         int rc = IntNetR0IfWait(pSession->hIfWait, pSession, 30000); /* 30s - don't wait forever, timeout now and then. */
    454         if (RT_SUCCESS(rc))
    455         {
    456             /* Send an empty message. */
    457             xpc_object_t hObjPoke = xpc_dictionary_create(NULL, NULL, 0);
    458             xpc_connection_send_message(pSession->hXpcCon, hObjPoke);
    459         }
    460         else if (   rc != VERR_TIMEOUT
    461                  && rc != VERR_INTERRUPTED)
    462         {
    463             LogFlow(("intnetR3RecvThread: returns %Rrc\n", rc));
    464             return rc;
    465         }
    466     }
    467 
    468     return VINF_SUCCESS;
     431    if (ASMAtomicXchgBool(&pSession->fRecvWait, false))
     432    {
     433        /* Send an empty message. */
     434        xpc_object_t hObjPoke = xpc_dictionary_create(NULL, NULL, 0);
     435        xpc_connection_send_message(pSession->hXpcCon, hObjPoke);
     436    }
     437    else
     438        ASMAtomicXchgBool(&pSession->fRecvAvail, true);
    469439}
    470440
     
    500470                if (cbReq == sizeof(INTNETOPENREQ))
    501471                {
    502                     rc = IntNetR0OpenReq(pSession, &ReqReply.OpenReq);
     472                    rc = IntNetR3Open(pSession, &ReqReply.OpenReq.szNetwork[0], ReqReply.OpenReq.enmTrunkType, ReqReply.OpenReq.szTrunk,
     473                                      ReqReply.OpenReq.fFlags, ReqReply.OpenReq.cbSend, ReqReply.OpenReq.cbRecv,
     474                                      intnetR3RecvAvail, pSession, &ReqReply.OpenReq.hIf);
    503475                    cbReply = sizeof(INTNETOPENREQ);
    504476                }
     
    525497                    /* This is special as we need to return a shared memory segment. */
    526498                    xpc_object_t hObjReply = xpc_dictionary_create_reply(hObj);
    527                     xpc_dictionary_set_int64(hObjReply, "rc", rc);
    528499                    xpc_object_t hObjShMem = xpc_shmem_create(ReqReply.IfGetBufferPtrsReq.pRing3Buf, ReqReply.IfGetBufferPtrsReq.pRing3Buf->cbBuf);
    529                     xpc_dictionary_set_value(hObjReply, "buf-ptr", hObjShMem);
    530                     xpc_release(hObjShMem);
     500                    if (hObjShMem)
     501                    {
     502                        xpc_dictionary_set_value(hObjReply, "buf-ptr", hObjShMem);
     503                        xpc_release(hObjShMem);
     504                    }
     505                    else
     506                        rc = VERR_NO_MEMORY;
     507
     508                    xpc_dictionary_set_uint64(hObjReply, "rc", INTNET_R3_SVC_SET_RC(rc));
    531509                    xpc_connection_send_message(hCon, hObjReply);
    532510                    return;
     
    584562                if (cbReq == sizeof(INTNETIFWAITREQ))
    585563                {
    586                     pSession->hIfWait = ReqReply.IfWaitReq.hIf; /* Asynchronous. */
    587                     rc = RTSemEventSignal(pSession->hEvtRecv);
     564                    ASMAtomicXchgBool(&pSession->fRecvWait, true);
     565                    if (ASMAtomicXchgBool(&pSession->fRecvAvail, false))
     566                    {
     567                        ASMAtomicXchgBool(&pSession->fRecvWait, false);
     568
     569                        /* Send an empty message. */
     570                        xpc_object_t hObjPoke = xpc_dictionary_create(NULL, NULL, 0);
     571                        xpc_connection_send_message(pSession->hXpcCon, hObjPoke);
     572                    }
    588573                    return;
    589574                }
     
    596581                if (cbReq == sizeof(INTNETIFABORTWAITREQ))
    597582                {
    598                     rc = IntNetR0IfAbortWaitReq(pSession, &ReqReply.IfAbortWaitReq);
     583                    ASMAtomicXchgBool(&pSession->fRecvWait, false);
     584                    if (ASMAtomicXchgBool(&pSession->fRecvAvail, false))
     585                    {
     586                        /* Send an empty message. */
     587                        xpc_object_t hObjPoke = xpc_dictionary_create(NULL, NULL, 0);
     588                        xpc_connection_send_message(pSession->hXpcCon, hObjPoke);
     589                    }
    599590                    cbReply = sizeof(INTNETIFABORTWAITREQ);
    600591                }
     
    609600
    610601    xpc_object_t hObjReply = xpc_dictionary_create_reply(hObj);
    611     xpc_dictionary_set_int64(hObjReply, "rc", rc);
     602    xpc_dictionary_set_uint64(hObjReply, "rc", INTNET_R3_SVC_SET_RC(rc));
    612603    xpc_dictionary_set_data(hObjReply, "reply", &ReqReply, cbReply);
    613604    xpc_connection_send_message(hCon, hObjReply);
     
    646637        pSession->hXpcCon = hXpcCon;
    647638
    648         int rc = RTSemEventCreate(&pSession->hEvtRecv);
    649         if (RT_SUCCESS(rc))
    650         {
    651             rc = RTThreadCreate(&pSession->hThrdRecv, intnetR3RecvThread, pSession, 0,
    652                                 RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "INTNET-RECV");
    653             if (RT_SUCCESS(rc))
    654             {
    655                 xpc_connection_set_context(hXpcCon, pSession);
    656                 xpc_connection_resume(hXpcCon);
    657                 xpc_transaction_begin();
    658                 ASMAtomicIncU32(&g_DevExt.cRefs);
    659                 return;
    660             }
    661 
    662             RTSemEventDestroy(pSession->hEvtRecv);
    663         }
    664 
    665         RTMemFree(pSession);
     639        xpc_connection_set_context(hXpcCon, pSession);
     640        xpc_connection_activate(hXpcCon);
     641        xpc_transaction_begin();
     642        ASMAtomicIncU32(&g_DevExt.cRefs);
    666643    }
    667644}
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