Changeset 97338 in vbox
- Timestamp:
- Oct 31, 2022 8:15:38 AM (2 years ago)
- Location:
- trunk
- Files:
-
- 5 edited
- 1 moved
-
include/VBox/intnet.h (modified) (2 diffs)
-
src/VBox/Devices/Network/DrvIntNet.cpp (modified) (3 diffs)
-
src/VBox/Devices/Network/SrvIntNetR0.cpp (modified) (24 diffs)
-
src/VBox/Devices/Network/testcase/tstIntNetR0.cpp (modified) (2 diffs)
-
src/VBox/NetworkServices/IntNetSwitch/Makefile.kmk (modified) (1 diff)
-
src/VBox/NetworkServices/IntNetSwitch/VBoxIntNetSwitch.cpp (moved) (moved from trunk/src/VBox/NetworkServices/IntNetSwitch/main.cpp ) (11 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/intnet.h
r97046 r97338 51 51 /** The userspace internal network service identifier. */ 52 52 #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) 54 64 #endif 55 65 … … 1317 1327 #endif /* IN_RING0 */ 1318 1328 1329 /** 1330 * Callback function for use with IntNetR3Open to signalling incoming data. 1331 * 1332 * @param hIf Interface handle. 1333 * @param pvUser User parameter. 1334 */ 1335 typedef DECLCALLBACKTYPE(void, FNINTNETIFRECVAVAIL,(INTNETIFHANDLE hIf, void *pvUser)); 1336 /** Pointer to a FNINTNETIFRECVAVAIL callback. */ 1337 typedef FNINTNETIFRECVAVAIL *PFNINTNETIFRECVAVAIL; 1338 1339 #if defined(VBOX_WITH_INTNET_SERVICE_IN_R3) && defined(IN_RING3) 1340 INTNETR3DECL(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 1319 1346 RT_C_DECLS_END 1320 1347 -
trunk/src/VBox/Devices/Network/DrvIntNet.cpp
r97089 r97338 249 249 xpc_dictionary_set_data(hObj, "req", pvArg, cbArg); 250 250 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 257 263 xpc_release(hObjReply); 258 259 return rc; 264 return VERR_INVALID_STATE; 260 265 } 261 266 else … … 316 321 xpc_dictionary_set_data(hObj, "req", &GetBufferPtrsReq, sizeof(GetBufferPtrsReq)); 317 322 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 319 329 if (RT_SUCCESS(rc)) 320 330 { … … 327 337 pThis->cbBuf = cbMem; 328 338 } 339 329 340 xpc_release(hObjReply); 330 341 } -
trunk/src/VBox/Devices/Network/SrvIntNetR0.cpp
r96407 r97338 245 245 /** Pointer to ring-3 mapping of the default exchange buffer. */ 246 246 R3PTRTYPE(PINTNETBUF) pIntBufDefaultR3; 247 #if !defined(VBOX_WITH_INTNET_SERVICE_IN_R3) || !defined(IN_RING3) 247 248 /** Event semaphore which a receiver/consumer thread will sleep on while 248 249 * waiting for data to arrive. */ … … 250 251 /** Number of threads sleeping on the event semaphore. */ 251 252 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 252 259 /** The interface handle. 253 260 * When this is INTNET_HANDLE_INVALID a sleeper which is waking up … … 2833 2840 2834 2841 2842 /** 2843 * Notifies consumers of incoming data from @a pIf that data is available. 2844 */ 2845 DECL_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 2835 2855 /** 2836 2856 * Sends a frame to a specific interface. … … 2852 2872 { 2853 2873 pIf->cYields = 0; 2854 RTSemEventSignal(pIf->hRecvEvent);2874 intnetR0IfNotifyRecv(pIf); 2855 2875 return; 2856 2876 } … … 2870 2890 while (--cYields > 0) 2871 2891 { 2872 RTSemEventSignal(pIf->hRecvEvent);2892 intnetR0IfNotifyRecv(pIf); 2873 2893 RTThreadYield(); 2874 2894 … … 2879 2899 { 2880 2900 STAM_REL_COUNTER_INC(&pIf->pIntBuf->cStatYieldsOk); 2881 RTSemEventSignal(pIf->hRecvEvent);2901 intnetR0IfNotifyRecv(pIf); 2882 2902 return; 2883 2903 } … … 2889 2909 /* ok, the frame is lost. */ 2890 2910 STAM_REL_COUNTER_INC(&pIf->pIntBuf->cStatLost); 2891 RTSemEventSignal(pIf->hRecvEvent);2911 intnetR0IfNotifyRecv(pIf); 2892 2912 } 2893 2913 … … 4667 4687 } 4668 4688 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; 4670 4694 const bool fNoMoreWaits = ASMAtomicUoReadBool(&pIf->fNoMoreWaits); 4671 4695 RTNATIVETHREAD hDtorThrd; … … 4721 4745 Log4(("IntNetR0IfWait: returns %Rrc\n", rc)); 4722 4746 return rc; 4747 #endif 4723 4748 } 4724 4749 … … 4765 4790 } 4766 4791 4792 #if defined(VBOX_WITH_INTNET_SERVICE_IN_R3) && defined(IN_RING3) 4793 AssertReleaseFailed(); 4794 return VERR_NOT_SUPPORTED; 4795 #else 4767 4796 const RTSEMEVENT hRecvEvent = pIf->hRecvEvent; 4768 4797 RTNATIVETHREAD hDtorThrd; … … 4807 4836 Log4(("IntNetR0IfWait: returns %Rrc\n", VINF_SUCCESS)); 4808 4837 return VINF_SUCCESS; 4838 #endif 4809 4839 } 4810 4840 … … 4851 4881 ASMAtomicWriteU32(&pIf->hIf, INTNET_HANDLE_INVALID); 4852 4882 4883 #if !defined(VBOX_WITH_INTNET_SERVICE_IN_R3) || !defined(IN_RING3) 4853 4884 /* 4854 4885 * Signal the event semaphore to wake up any threads in IntNetR0IfWait … … 4862 4893 } 4863 4894 RTSemEventSignal(pIf->hRecvEvent); 4895 #endif 4864 4896 4865 4897 /* … … 5000 5032 RTSemMutexRelease(pIntNet->hMtxCreateOpenDestroy); 5001 5033 5034 #if !defined(VBOX_WITH_INTNET_SERVICE_IN_R3) || !defined(IN_RING3) 5002 5035 /* 5003 5036 * Wakeup anyone waiting on this interface. (Kind of unlikely, but perhaps … … 5031 5064 pIf->hRecvEvent = NIL_RTSEMEVENT; 5032 5065 } 5066 #endif 5033 5067 5034 5068 /* … … 5080 5114 * 5081 5115 * @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 */ 5127 static int intnetR0NetworkCreateIf(PINTNETNETWORK pNetwork, PSUPDRVSESSION pSession, unsigned cbSend, unsigned cbRecv, 5128 uint32_t fFlags, PFNINTNETIFRECVAVAIL pfnRecvAvail, void *pvUser, PINTNETIFHANDLE phIf) 5093 5129 { 5094 5130 LogFlow(("intnetR0NetworkCreateIf: pNetwork=%p pSession=%p cbSend=%u cbRecv=%u fFlags=%#x phIf=%p\n", … … 5100 5136 AssertPtr(pNetwork); 5101 5137 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 5102 5143 5103 5144 /* … … 5136 5177 //pIf->pIntBufDefault = 0; 5137 5178 //pIf->pIntBufDefaultR3 = NIL_RTR3PTR; 5179 #if !defined(VBOX_WITH_INTNET_SERVICE_IN_R3) || !defined(IN_RING3) 5138 5180 pIf->hRecvEvent = NIL_RTSEMEVENT; 5181 #else 5182 pIf->pfnRecvAvail = pfnRecvAvail; 5183 pIf->pvUserRecvAvail = pvUser; 5184 #endif 5139 5185 //pIf->cSleepers = 0; 5140 5186 pIf->hIf = INTNET_HANDLE_INVALID; … … 5154 5200 if (RT_SUCCESS(rc)) 5155 5201 rc = intnetR0AllocDstTab(pNetwork->MacTab.cEntriesAllocated, (PINTNETDSTTAB *)&pIf->pDstTab); 5202 #if !defined(VBOX_WITH_INTNET_SERVICE_IN_R3) || !defined(IN_RING3) 5156 5203 if (RT_SUCCESS(rc)) 5157 5204 rc = RTSemEventCreate((PRTSEMEVENT)&pIf->hRecvEvent); 5205 #endif 5158 5206 if (RT_SUCCESS(rc)) 5159 5207 rc = RTSpinlockCreate(&pIf->hRecvInSpinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "hRecvInSpinlock"); … … 5248 5296 RTSpinlockDestroy(pIf->hRecvInSpinlock); 5249 5297 pIf->hRecvInSpinlock = NIL_RTSPINLOCK; 5298 #if !defined(VBOX_WITH_INTNET_SERVICE_IN_R3) || !defined(IN_RING3) 5250 5299 RTSemEventDestroy(pIf->hRecvEvent); 5251 5300 pIf->hRecvEvent = NIL_RTSEMEVENT; 5301 #else 5302 pIf->pfnRecvAvail = NULL; 5303 pIf->pvUserRecvAvail = NULL; 5304 #endif 5252 5305 RTMemFree(pIf->pDstTab); 5253 5306 for (int i = kIntNetAddrType_Invalid + 1; i < kIntNetAddrType_End; i++) … … 6594 6647 * @param pszTrunk The trunk name. Its meaning is specific to the type. 6595 6648 * @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. 6597 6651 * @param cbSend The send buffer size. 6598 6652 * @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. 6599 6656 * @param phIf Where to store the handle to the network interface. 6600 6657 */ 6601 6658 INTNETR0DECL(int) IntNetR0Open(PSUPDRVSESSION pSession, const char *pszNetwork, 6602 6659 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) 6604 6662 { 6605 6663 LogFlow(("IntNetR0Open: pSession=%p pszNetwork=%p:{%s} enmTrunkType=%d pszTrunk=%p:{%s} fFlags=%#x cbSend=%u cbRecv=%u phIf=%p\n", … … 6675 6733 if (RT_SUCCESS(rc)) 6676 6734 { 6677 rc = intnetR0NetworkCreateIf(pNetwork, pSession, cbSend, cbRecv, fFlags, p hIf);6735 rc = intnetR0NetworkCreateIf(pNetwork, pSession, cbSend, cbRecv, fFlags, pfnRecvAvail, pvUser, phIf); 6678 6736 if (RT_SUCCESS(rc)) 6679 6737 { … … 6689 6747 if (RT_SUCCESS(rc)) 6690 6748 { 6691 rc = intnetR0NetworkCreateIf(pNetwork, pSession, cbSend, cbRecv, fFlags, p hIf);6749 rc = intnetR0NetworkCreateIf(pNetwork, pSession, cbSend, cbRecv, fFlags, pfnRecvAvail, pvUser, phIf); 6692 6750 if (RT_FAILURE(rc)) 6693 6751 SUPR0ObjRelease(pNetwork->pvObj, pSession); … … 6713 6771 return VERR_INVALID_PARAMETER; 6714 6772 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) 6778 INTNETR3DECL(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 6717 6786 6718 6787 -
trunk/src/VBox/Devices/Network/testcase/tstIntNetR0.cpp
r97300 r97338 447 447 { 448 448 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); 451 451 RTTESTI_CHECK_RET(pThis->hIf0 != INTNET_HANDLE_INVALID, VERR_INTERNAL_ERROR); 452 452 RTTESTI_CHECK_RC_RET(IntNetR0IfGetBufferPtrs(pThis->hIf0, g_pSession, &pThis->pBuf0, NULL), VINF_SUCCESS, rcCheck); … … 455 455 456 456 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); 459 459 RTTESTI_CHECK_RET(pThis->hIf1 != INTNET_HANDLE_INVALID, VERR_INTERNAL_ERROR); 460 460 RTTESTI_CHECK_RC_RET(IntNetR0IfGetBufferPtrs(pThis->hIf1, g_pSession, &pThis->pBuf1, NULL), VINF_SUCCESS, rcCheck); -
trunk/src/VBox/NetworkServices/IntNetSwitch/Makefile.kmk
r97122 r97338 40 40 VBoxIntNetSwitch_DEFS = KBUILD_TYPE=\"$(KBUILD_TYPE)\" 41 41 endif 42 VBoxIntNetSwitch_DEFS += VBOX_WITH_INTNET_SERVICE_IN_R3 42 43 VBoxIntNetSwitch_INST.darwin = $(VBoxIntNetSwitch.xpc_INST)/MacOS/ 43 44 VBoxIntNetSwitch_SOURCES = \ 44 main.cpp \45 VBoxIntNetSwitch.cpp \ 45 46 SrvIntNetWrapper.cpp 46 47 VBoxIntNetSwitch_LIBS = $(LIB_RUNTIME) -
trunk/src/VBox/NetworkServices/IntNetSwitch/VBoxIntNetSwitch.cpp
r97337 r97338 53 53 54 54 /********************************************************************************************************************************* 55 * Defined Constants And Macros * 56 *********************************************************************************************************************************/ 57 58 59 /********************************************************************************************************************************* 55 60 * Structures and Typedefs * 56 61 *********************************************************************************************************************************/ … … 116 121 /** The XPC connection handle for this session. */ 117 122 xpc_connection_t hXpcCon; 118 /** The receive wait thread. */119 RTTHREAD hThrdRecv;120 123 /** The intnet interface handle to wait on. */ 121 124 INTNETIFHANDLE hIfWait; 122 /** The event semaphore for the receive thread. */123 RTSEMEVENT hEvtRecv;124 /** Flag whether t o terminate the receive thread. */125 bool volatile f Terminate;125 /** Flag whether a receive wait was initiated. */ 126 bool volatile fRecvWait; 127 /** Flag whether there is something to receive. */ 128 bool volatile fRecvAvail; 126 129 } SUPDRVSESSION; 127 130 … … 357 360 PSUPDRVDEVEXT pDevExt = pSession->pDevExt; 358 361 uint32_t cRefs = ASMAtomicDecU32(&pDevExt->cRefs); 362 xpc_transaction_end(); 359 363 xpc_connection_set_context(pSession->hXpcCon, NULL); 360 364 xpc_connection_cancel(pSession->hXpcCon); 361 365 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); 377 368 378 369 if (pSession->pUsage) … … 422 413 423 414 RTCritSectLeave(&pDevExt->CritSect); 424 AssertMsg(!pSession->pUsage, ("Some buster reregistered an object during dest urction!\n"));415 AssertMsg(!pSession->pUsage, ("Some buster reregistered an object during destruction!\n")); 425 416 } 426 417 … … 431 422 432 423 /** 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 */ 426 static DECLCALLBACK(void) intnetR3RecvAvail(INTNETIFHANDLE hIf, void *pvUser) 427 { 428 RT_NOREF(hIf); 442 429 PSUPDRVSESSION pSession = (PSUPDRVSESSION)pvUser; 443 430 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); 469 439 } 470 440 … … 500 470 if (cbReq == sizeof(INTNETOPENREQ)) 501 471 { 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); 503 475 cbReply = sizeof(INTNETOPENREQ); 504 476 } … … 525 497 /* This is special as we need to return a shared memory segment. */ 526 498 xpc_object_t hObjReply = xpc_dictionary_create_reply(hObj); 527 xpc_dictionary_set_int64(hObjReply, "rc", rc);528 499 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)); 531 509 xpc_connection_send_message(hCon, hObjReply); 532 510 return; … … 584 562 if (cbReq == sizeof(INTNETIFWAITREQ)) 585 563 { 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 } 588 573 return; 589 574 } … … 596 581 if (cbReq == sizeof(INTNETIFABORTWAITREQ)) 597 582 { 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 } 599 590 cbReply = sizeof(INTNETIFABORTWAITREQ); 600 591 } … … 609 600 610 601 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)); 612 603 xpc_dictionary_set_data(hObjReply, "reply", &ReqReply, cbReply); 613 604 xpc_connection_send_message(hCon, hObjReply); … … 646 637 pSession->hXpcCon = hXpcCon; 647 638 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); 666 643 } 667 644 }
Note:
See TracChangeset
for help on using the changeset viewer.

