Changeset 90238 in vbox
- Timestamp:
- Jul 19, 2021 1:48:09 PM (4 years ago)
- svn:sync-xref-src-repo-rev:
- 145776
- Location:
- trunk
- Files:
-
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/err.h
r90161 r90238 1623 1623 /** Requested service already exists. */ 1624 1624 #define VERR_HGCM_SERVICE_EXISTS (-2907) 1625 1625 /** Too many clients for the service. */ 1626 #define VERR_HGCM_TOO_MANY_CLIENTS (-2908) 1627 /** Too many calls to the service from a client. */ 1628 #define VERR_HGCM_TOO_MANY_CLIENT_CALLS (-2909) 1626 1629 /** @} */ 1627 1630 -
trunk/include/VBox/hgcmsvc.h
r85121 r90238 81 81 * 6.5->7.1 Because pfnNotify was added (VBox 6.0). 82 82 * 7.1->8.1 Because pfnCancelled & pfnIsCallCancelled were added (VBox 6.0). 83 * 8.1->9.1 Because pfnDisconnectClient was (temporarily) removed, and 84 * acMaxClients and acMaxCallsPerClient added (VBox 6.1.26). 83 85 */ 84 #define VBOX_HGCM_SVC_VERSION_MAJOR (0x000 8)86 #define VBOX_HGCM_SVC_VERSION_MAJOR (0x0009) 85 87 #define VBOX_HGCM_SVC_VERSION_MINOR (0x0001) 86 88 #define VBOX_HGCM_SVC_VERSION ((VBOX_HGCM_SVC_VERSION_MAJOR << 16) + VBOX_HGCM_SVC_VERSION_MINOR) … … 99 101 void *pvInstance; 100 102 103 #if 0 /* Not thread safe. */ 101 104 /** The service disconnects the client. */ 102 105 DECLR3CALLBACKMEMBER(void, pfnDisconnectClient, (void *pvInstance, uint32_t u32ClientID)); 106 #endif 103 107 104 108 /** … … 594 598 } HGCMNOTIFYEVENT; 595 599 600 /** @name HGCM_CLIENT_CATEGORY_XXX - Client categories 601 * @{ */ 602 #define HGCM_CLIENT_CATEGORY_KERNEL 0 /**< Guest kernel mode and legacy client. */ 603 #define HGCM_CLIENT_CATEGORY_ROOT 1 /**< Guest root or admin client. */ 604 #define HGCM_CLIENT_CATEGORY_USER 2 /**< Regular guest user client. */ 605 #define HGCM_CLIENT_CATEGORY_MAX 3 /**< Max number of categories. */ 606 /** @} */ 607 596 608 597 609 /** The Service DLL entry points. … … 610 622 611 623 /** Size of the structure. */ 612 uint32_t 613 614 /** Version of the structure, including the helpers. */615 uint32_t 616 617 PVBOXHGCMSVCHELPERS 624 uint32_t cbSize; 625 626 /** Version of the structure, including the helpers. (VBOX_HGCM_SVC_VERSION) */ 627 uint32_t u32Version; 628 629 PVBOXHGCMSVCHELPERS pHelpers; 618 630 /** @} */ 619 631 … … 622 634 623 635 /** Size of client information the service want to have. */ 624 uint32_t cbClient; 625 #if ARCH_BITS == 64 626 /** Ensure that the following pointers are properly aligned on 64-bit system. */ 627 uint32_t u32Alignment0; 628 #endif 636 uint32_t cbClient; 637 638 /** The maximum number of clients per category. Leave entries as zero for defaults. */ 639 uint32_t acMaxClients[HGCM_CLIENT_CATEGORY_MAX]; 640 /** The maximum number of concurrent calls per client for each category. 641 * Leave entries as as zero for default. */ 642 uint32_t acMaxCallsPerClient[HGCM_CLIENT_CATEGORY_MAX]; 643 /** The HGCM_CLIENT_CATEGORY_XXX value for legacy clients. 644 * Defaults to HGCM_CLIENT_CATEGORY_KERNEL. */ 645 uint32_t idxLegacyClientCategory; 629 646 630 647 /** Uninitialize service */ -
trunk/src/VBox/HostServices/DragAndDrop/VBoxDragAndDropSvc.cpp
r86869 r90238 181 181 int DragAndDropService::init(VBOXHGCMSVCFNTABLE *pTable) RT_NOEXCEPT 182 182 { 183 /* Legacy clients map to the root category. */ 184 pTable->idxLegacyClientCategory = HGCM_CLIENT_CATEGORY_ROOT; 185 186 /* Limit to 255 clients (see also DragAndDropService::clientConnect). */ 187 for (uintptr_t i = 0; i < RT_ELEMENTS(pTable->acMaxClients); i++) 188 pTable->acMaxClients[i] = UINT8_MAX; 189 190 /* Limit the number of concurrent calls to 256 (playing safe). */ 191 /** @todo Properly determin the max number of pending/concurrent calls for DnD. */ 192 for (uintptr_t i = 0; i < RT_ELEMENTS(pTable->acMaxClients); i++) 193 pTable->acMaxCallsPerClient[i] = 256; 194 183 195 /* Register functions. */ 184 196 pTable->pfnHostCall = svcHostCall; -
trunk/src/VBox/HostServices/GuestControl/VBoxGuestControlSvc.cpp
r87624 r90238 2534 2534 pTable->cbClient = sizeof(ClientState); 2535 2535 2536 /* Limit pending calls to 8 pending per connection (doubt we need more than 2537 one). Map legacy clients to the root and limit kernel to 1 (zero would 2538 be default) and use defaults for root and user clients. */ 2539 for (uintptr_t i = 0; i < RT_ELEMENTS(pTable->acMaxClients); i++) 2540 pTable->acMaxCallsPerClient[i] = 8; 2541 2542 pTable->idxLegacyClientCategory = HGCM_CLIENT_CATEGORY_ROOT; 2543 pTable->acMaxClients[HGCM_CLIENT_CATEGORY_KERNEL] = 1; 2544 2536 2545 /* Register functions. */ 2537 2546 pTable->pfnUnload = GstCtrlService::svcUnload; -
trunk/src/VBox/HostServices/GuestProperties/VBoxGuestPropSvc.cpp
r85121 r90238 1865 1865 ptable->cbClient = 0; 1866 1866 1867 /* Legacy clients map to the kernel category. */ 1868 ptable->idxLegacyClientCategory = HGCM_CLIENT_CATEGORY_KERNEL; 1869 1870 /* Go with default client limits, but we won't ever need more than 1871 16 pending calls per client I would think (1 should be enough). */ 1872 for (uintptr_t i = 0; i < RT_ELEMENTS(ptable->acMaxClients); i++) 1873 ptable->acMaxCallsPerClient[i] = 16; 1874 1867 1875 ptable->pfnUnload = Service::svcUnload; 1868 1876 ptable->pfnConnect = Service::svcConnect; -
trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-darwin.cpp
r86889 r90238 119 119 120 120 121 int ShClBackendInit(void) 122 { 121 int ShClBackendInit(VBOXHGCMSVCFNTABLE *pTable) 122 { 123 RT_NOREF(pTable); 123 124 g_ctx.fTerminate = false; 124 125 -
trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-internal.h
r87566 r90238 306 306 /** 307 307 * Called on initialization. 308 */ 309 int ShClBackendInit(void); 308 * 309 * @param pTable The HGCM service call and parameter table. Mainly for 310 * adjusting the limits. 311 */ 312 int ShClBackendInit(VBOXHGCMSVCFNTABLE *pTable); 310 313 311 314 /** -
trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-win.cpp
r90054 r90238 604 604 */ 605 605 606 int ShClBackendInit(void) 607 { 606 int ShClBackendInit(VBOXHGCMSVCFNTABLE *pTable) 607 { 608 RT_NOREF(pTable); 608 609 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS 609 610 HRESULT hr = OleInitialize(NULL); -
trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-x11-stubs.cpp
r87566 r90238 41 41 * Initialise the host side of the shared clipboard - called by the hgcm layer. 42 42 */ 43 int ShClBackendInit( void)43 int ShClBackendInit(VBOXHGCMSVCFNTABLE *pTable) 44 44 { 45 RT_NOREF(pTable); 45 46 LogFlowFunc(("called, returning VINF_SUCCESS\n")); 46 47 return VINF_SUCCESS; -
trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-x11.cpp
r89948 r90238 61 61 62 62 63 int ShClBackendInit(void) 64 { 65 LogFlowFuncEnter(); 63 int ShClBackendInit(VBOXHGCMSVCFNTABLE *pTable) 64 { 65 LogFlowFuncEnter(); 66 67 /* Override the connection limit. */ 68 for (uintptr_t i = 0; i < RT_ELEMENTS(pTable->acMaxClients); i++) 69 pTable->acMaxClients[i] = RT_MIN(VBOX_SHARED_CLIPBOARD_X11_CONNECTIONS_MAX, pTable->acMaxClients[i]); 70 66 71 return VINF_SUCCESS; 67 72 } -
trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc.cpp
r89947 r90238 1932 1932 } 1933 1933 1934 static int svcInit( void)1934 static int svcInit(VBOXHGCMSVCFNTABLE *pTable) 1935 1935 { 1936 1936 int rc = RTCritSectInit(&g_CritSect); … … 1940 1940 shClSvcModeSet(VBOX_SHCL_MODE_OFF); 1941 1941 1942 rc = ShClBackendInit( );1942 rc = ShClBackendInit(pTable); 1943 1943 1944 1944 /* Clean up on failure, because 'svnUnload' will not be called … … 2722 2722 pTable->cbClient = sizeof(SHCLCLIENT); 2723 2723 2724 /* Map legacy clients to root. */ 2725 pTable->idxLegacyClientCategory = HGCM_CLIENT_CATEGORY_ROOT; 2726 2727 /* Limit the number of clients to 128 in each category (should be enough), 2728 but set kernel clients to 1 (zero would be default). */ 2729 for (uintptr_t i = 0; i < RT_ELEMENTS(pTable->acMaxClients); i++) 2730 pTable->acMaxClients[i] = 128; 2731 pTable->acMaxClients[HGCM_CLIENT_CATEGORY_KERNEL] = 1; 2732 2733 /* Only 16 pending calls per client (1 should be enough). */ 2734 for (uintptr_t i = 0; i < RT_ELEMENTS(pTable->acMaxClients); i++) 2735 pTable->acMaxCallsPerClient[i] = 16; 2736 2724 2737 pTable->pfnUnload = svcUnload; 2725 2738 pTable->pfnConnect = svcConnect; … … 2734 2747 2735 2748 /* Service specific initialization. */ 2736 rc = svcInit( );2749 rc = svcInit(pTable); 2737 2750 } 2738 2751 } -
trunk/src/VBox/HostServices/SharedClipboard/testcase/tstClipboardServiceHost.cpp
r86364 r90238 310 310 } 311 311 312 int ShClBackendInit( ) { return VINF_SUCCESS; }312 int ShClBackendInit(VBOXHGCMSVCFNTABLE *) { return VINF_SUCCESS; } 313 313 void ShClBackendDestroy() { } 314 314 int ShClBackendDisconnect(PSHCLCLIENT) { return VINF_SUCCESS; } -
trunk/src/VBox/HostServices/SharedClipboard/testcase/tstClipboardServiceImpl.cpp
r84142 r90238 52 52 } 53 53 54 int ShClBackendInit( void) { return VINF_SUCCESS; }54 int ShClBackendInit(VBOXHGCMSVCFNTABLE *) { return VINF_SUCCESS; } 55 55 void ShClBackendDestroy(void) { } 56 56 int ShClBackendDisconnect(PSHCLCLIENT) { return VINF_SUCCESS; } -
trunk/src/VBox/HostServices/SharedFolders/VBoxSharedFoldersSvc.cpp
r82968 r90238 1851 1851 ptable->cbClient = sizeof (SHFLCLIENTDATA); 1852 1852 1853 /* Map legacy clients to the kernel category. */ 1854 ptable->idxLegacyClientCategory = HGCM_CLIENT_CATEGORY_KERNEL; 1855 1856 /* Only 64K pending calls per kernel client, root gets 16K and regular users 1K. */ 1857 ptable->acMaxCallsPerClient[HGCM_CLIENT_CATEGORY_KERNEL] = _64K; 1858 ptable->acMaxCallsPerClient[HGCM_CLIENT_CATEGORY_ROOT] = _16K; 1859 ptable->acMaxCallsPerClient[HGCM_CLIENT_CATEGORY_USER] = _1K; 1860 1861 /* Reduce the number of clients to SHFL_MAX_MAPPINGS + 2 in each category, 1862 so the increased calls-per-client value causes less trouble. 1863 ((64 + 2) * 3 * 65536 = 12 976 128) */ 1864 for (uintptr_t i = 0; i < RT_ELEMENTS(ptable->acMaxClients); i++) 1865 ptable->acMaxClients[i] = SHFL_MAX_MAPPINGS + 2; 1866 1853 1867 ptable->pfnUnload = svcUnload; 1854 1868 ptable->pfnConnect = svcConnect; -
trunk/src/VBox/Main/src-client/HGCM.cpp
r90229 r90238 27 27 #include <VBox/vmm/stam.h> 28 28 #include <VBox/sup.h> 29 #include <VBox/AssertGuest.h> 29 30 30 31 #include <iprt/alloc.h> … … 108 109 VBOXHGCMSVCFNTABLE m_fntable; 109 110 111 uint32_t m_acClients[HGCM_CLIENT_CATEGORY_MAX]; /**< Clients per category. */ 110 112 uint32_t m_cClients; 111 113 uint32_t m_cClientsAllocated; … … 121 123 * @{ */ 122 124 STAMPROFILE m_StatHandleMsg; 125 STAMCOUNTER m_StatTooManyClients; 126 STAMCOUNTER m_StatTooManyCalls; 123 127 /** @} */ 124 128 … … 187 191 */ 188 192 189 int GuestCall(PPDMIHGCMPORT pHGCMPort, PVBOXHGCMCMD pCmd, uint32_t u32ClientId, 193 int GuestCall(PPDMIHGCMPORT pHGCMPort, PVBOXHGCMCMD pCmd, uint32_t u32ClientId, HGCMClient *pClient, 190 194 uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM aParms[], uint64_t tsArrival); 191 195 void GuestCancelled(PPDMIHGCMPORT pHGCMPort, PVBOXHGCMCMD pCmd, uint32_t idClient); … … 196 200 { 197 201 public: 198 HGCMClient(uint32_t a_fRequestor )202 HGCMClient(uint32_t a_fRequestor, uint32_t a_idxCategory) 199 203 : HGCMObject(HGCMOBJ_CLIENT) 200 204 , pService(NULL) 201 205 , pvData(NULL) 202 206 , fRequestor(a_fRequestor) 203 {} 207 , idxCategory(a_idxCategory) 208 , cPendingCalls(0) 209 { 210 Assert(idxCategory < HGCM_CLIENT_CATEGORY_MAX); 211 } 204 212 ~HGCMClient(); 205 213 … … 215 223 * @sa VMMDevRequestHeader::fRequestor */ 216 224 uint32_t fRequestor; 225 226 /** The client category (HGCM_CLIENT_CATEGORY_XXX). */ 227 uint32_t idxCategory; 228 229 /** Number of pending calls. */ 230 uint32_t volatile cPendingCalls; 217 231 218 232 private: /* none of this: */ … … 275 289 m_pHgcmPort (NULL) 276 290 { 291 RT_ZERO(m_acClients); 277 292 RT_ZERO(m_fntable); 278 293 } … … 340 355 if (RT_SUCCESS(rc)) 341 356 { 342 if ( m_fntable.pfnUnload == NULL343 || m_fntable.pfnConnect == NULL344 || m_fntable.pfnDisconnect == NULL345 || m_fntable.pfnCall == NULL357 if ( m_fntable.pfnUnload != NULL 358 && m_fntable.pfnConnect != NULL 359 && m_fntable.pfnDisconnect != NULL 360 && m_fntable.pfnCall != NULL 346 361 ) 362 { 363 /* 364 * Set default limits if not filled in by the service. 365 * Total max calls: (2048 + 1024 + 1024) * 8192 = 33 554 432 366 */ 367 Assert(m_fntable.idxLegacyClientCategory < RT_ELEMENTS(m_fntable.acMaxClients)); 368 369 if (m_fntable.acMaxClients[HGCM_CLIENT_CATEGORY_KERNEL] == 0) 370 m_fntable.acMaxClients[HGCM_CLIENT_CATEGORY_KERNEL] = _2K; 371 if (m_fntable.acMaxClients[HGCM_CLIENT_CATEGORY_ROOT] == 0) 372 m_fntable.acMaxClients[HGCM_CLIENT_CATEGORY_ROOT] = _1K; 373 if (m_fntable.acMaxClients[HGCM_CLIENT_CATEGORY_USER] == 0) 374 m_fntable.acMaxClients[HGCM_CLIENT_CATEGORY_USER] = _1K; 375 376 if (m_fntable.acMaxCallsPerClient[HGCM_CLIENT_CATEGORY_KERNEL] == 0) 377 m_fntable.acMaxCallsPerClient[HGCM_CLIENT_CATEGORY_KERNEL] = _8K; 378 if (m_fntable.acMaxCallsPerClient[HGCM_CLIENT_CATEGORY_ROOT] == 0) 379 m_fntable.acMaxCallsPerClient[HGCM_CLIENT_CATEGORY_ROOT] = _4K; 380 if (m_fntable.acMaxCallsPerClient[HGCM_CLIENT_CATEGORY_USER] == 0) 381 m_fntable.acMaxCallsPerClient[HGCM_CLIENT_CATEGORY_USER] = _2K; 382 383 /** @todo provide way to configure different values via extra data. */ 384 385 LogRel2(("HGCMService::loadServiceDLL: acMaxClients={%u,%u,%u} acMaxCallsPerClient={%u,%u,%u} => %RU64 calls; idxLegacyClientCategory=%d; %s\n", 386 m_fntable.acMaxClients[HGCM_CLIENT_CATEGORY_KERNEL], 387 m_fntable.acMaxClients[HGCM_CLIENT_CATEGORY_ROOT], 388 m_fntable.acMaxClients[HGCM_CLIENT_CATEGORY_USER], 389 m_fntable.acMaxCallsPerClient[HGCM_CLIENT_CATEGORY_KERNEL], 390 m_fntable.acMaxCallsPerClient[HGCM_CLIENT_CATEGORY_ROOT], 391 m_fntable.acMaxCallsPerClient[HGCM_CLIENT_CATEGORY_USER], 392 (uint64_t)m_fntable.acMaxClients[HGCM_CLIENT_CATEGORY_KERNEL] 393 * m_fntable.acMaxCallsPerClient[HGCM_CLIENT_CATEGORY_KERNEL] 394 + (uint64_t)m_fntable.acMaxClients[HGCM_CLIENT_CATEGORY_ROOT] 395 * m_fntable.acMaxCallsPerClient[HGCM_CLIENT_CATEGORY_ROOT] 396 + (uint64_t)m_fntable.acMaxClients[HGCM_CLIENT_CATEGORY_USER] 397 * m_fntable.acMaxCallsPerClient[HGCM_CLIENT_CATEGORY_USER], 398 m_fntable.idxLegacyClientCategory, m_pszSvcName)); 399 } 400 else 347 401 { 348 402 Log(("HGCMService::loadServiceDLL: at least one of function pointers is NULL\n")); … … 455 509 { 456 510 public: 457 HGCMMsgCall() {} 511 HGCMMsgCall() : pcCounter(NULL) 512 { } 458 513 459 514 HGCMMsgCall(HGCMThread *pThread) 515 : pcCounter(NULL) 460 516 { 461 517 InitializeCore(SVC_MSG_GUESTCALL, pThread); 462 518 Initialize(); 463 519 } 464 ~HGCMMsgCall() { Log(("~HGCMMsgCall %p\n", this)); } 520 ~HGCMMsgCall() 521 { 522 Log(("~HGCMMsgCall %p\n", this)); 523 Assert(!pcCounter); 524 } 525 526 /** Points to HGCMClient::cPendingCalls if it needs to be decremented. */ 527 uint32_t volatile *pcCounter; 465 528 466 529 /* client identifier */ … … 861 924 } 862 925 926 #if 0 /* not thread safe */ 863 927 /** 864 928 * @interface_method_impl{VBOXHGCMSVCHELPERS,pfnDisconnectClient} … … 876 940 } 877 941 } 942 #endif 878 943 879 944 /** … … 1051 1116 STAMR3RegisterFU(pUVM, &m_StatHandleMsg, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, 1052 1117 "Message handling", "/HGCM/%s/Msg", pszServiceName); 1118 STAMR3RegisterFU(pUVM, &m_StatTooManyCalls, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, 1119 "Too many calls (per client)", "/HGCM/%s/TooManyCalls", pszServiceName); 1120 STAMR3RegisterFU(pUVM, &m_StatTooManyClients, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, 1121 "Too many clients", "/HGCM/%s/TooManyClients", pszServiceName); 1122 STAMR3RegisterFU(pUVM, &m_cClients, STAMTYPE_U32, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, 1123 "Number of clients", "/HGCM/%s/Clients", pszServiceName); 1124 STAMR3RegisterFU(pUVM, &m_acClients[HGCM_CLIENT_CATEGORY_KERNEL], STAMTYPE_U32, STAMVISIBILITY_ALWAYS, 1125 STAMUNIT_OCCURENCES, "Number of kernel clients", "/HGCM/%s/Clients/Kernel", pszServiceName); 1126 STAMR3RegisterFU(pUVM, &m_acClients[HGCM_CLIENT_CATEGORY_ROOT], STAMTYPE_U32, STAMVISIBILITY_ALWAYS, 1127 STAMUNIT_OCCURENCES, "Number of root/admin clients", "/HGCM/%s/Clients/Root", pszServiceName); 1128 STAMR3RegisterFU(pUVM, &m_acClients[HGCM_CLIENT_CATEGORY_USER], STAMTYPE_U32, STAMVISIBILITY_ALWAYS, 1129 STAMUNIT_OCCURENCES, "Number of regular user clients", "/HGCM/%s/Clients/User", pszServiceName); 1130 STAMR3RegisterFU(pUVM, &m_fntable.acMaxClients[HGCM_CLIENT_CATEGORY_KERNEL], STAMTYPE_U32, STAMVISIBILITY_ALWAYS, 1131 STAMUNIT_OCCURENCES, "Max number of kernel clients", "/HGCM/%s/Clients/KernelMax", pszServiceName); 1132 STAMR3RegisterFU(pUVM, &m_fntable.acMaxClients[HGCM_CLIENT_CATEGORY_ROOT], STAMTYPE_U32, STAMVISIBILITY_ALWAYS, 1133 STAMUNIT_OCCURENCES, "Max number of root clients", "/HGCM/%s/Clients/RootMax", pszServiceName); 1134 STAMR3RegisterFU(pUVM, &m_fntable.acMaxClients[HGCM_CLIENT_CATEGORY_USER], STAMTYPE_U32, STAMVISIBILITY_ALWAYS, 1135 STAMUNIT_OCCURENCES, "Max number of user clients", "/HGCM/%s/Clients/UserMax", pszServiceName); 1136 STAMR3RegisterFU(pUVM, &m_fntable.idxLegacyClientCategory, STAMTYPE_U32, STAMVISIBILITY_ALWAYS, 1137 STAMUNIT_OCCURENCES, "Legacy client mapping", "/HGCM/%s/Clients/LegacyClientMapping", pszServiceName); 1138 STAMR3RegisterFU(pUVM, &m_fntable.acMaxCallsPerClient[HGCM_CLIENT_CATEGORY_KERNEL], STAMTYPE_U32, STAMVISIBILITY_ALWAYS, 1139 STAMUNIT_OCCURENCES, "Max number of call per kernel client", "/HGCM/%s/MaxCallsKernelClient", pszServiceName); 1140 STAMR3RegisterFU(pUVM, &m_fntable.acMaxCallsPerClient[HGCM_CLIENT_CATEGORY_ROOT], STAMTYPE_U32, STAMVISIBILITY_ALWAYS, 1141 STAMUNIT_OCCURENCES, "Max number of call per root client", "/HGCM/%s/MaxCallsRootClient", pszServiceName); 1142 STAMR3RegisterFU(pUVM, &m_fntable.acMaxCallsPerClient[HGCM_CLIENT_CATEGORY_USER], STAMTYPE_U32, STAMVISIBILITY_ALWAYS, 1143 STAMUNIT_OCCURENCES, "Max number of call per user client", "/HGCM/%s/MaxCallsUserClient", pszServiceName); 1053 1144 1054 1145 /* Initialize service helpers table. */ 1055 1146 m_svcHelpers.pfnCallComplete = svcHlpCallComplete; 1056 1147 m_svcHelpers.pvInstance = this; 1148 #if 0 /* not thread safe */ 1057 1149 m_svcHelpers.pfnDisconnectClient = svcHlpDisconnectClient; 1150 #endif 1058 1151 m_svcHelpers.pfnIsCallRestored = svcHlpIsCallRestored; 1059 1152 m_svcHelpers.pfnIsCallCancelled = svcHlpIsCallCancelled; … … 1557 1650 pu32ClientIdOut, u32ClientIdIn, fRequestor, fRestoring)); 1558 1651 1652 /* 1653 * Categorize the client (compress VMMDEV_REQUESTOR_USR_MASK) 1654 * and check the respective client limit. 1655 */ 1656 uint32_t idxClientCategory; 1657 if (fRequestor == VMMDEV_REQUESTOR_LEGACY) 1658 { 1659 idxClientCategory = m_fntable.idxLegacyClientCategory; 1660 AssertStmt(idxClientCategory < RT_ELEMENTS(m_acClients), idxClientCategory = HGCM_CLIENT_CATEGORY_KERNEL); 1661 } 1662 else 1663 switch (fRequestor & VMMDEV_REQUESTOR_USR_MASK) 1664 { 1665 case VMMDEV_REQUESTOR_USR_DRV: 1666 case VMMDEV_REQUESTOR_USR_DRV_OTHER: 1667 idxClientCategory = HGCM_CLIENT_CATEGORY_KERNEL; 1668 break; 1669 case VMMDEV_REQUESTOR_USR_ROOT: 1670 case VMMDEV_REQUESTOR_USR_SYSTEM: 1671 idxClientCategory = HGCM_CLIENT_CATEGORY_ROOT; 1672 break; 1673 default: 1674 idxClientCategory = HGCM_CLIENT_CATEGORY_USER; 1675 break; 1676 } 1677 1678 if ( m_acClients[idxClientCategory] < m_fntable.acMaxClients[idxClientCategory] 1679 || fRestoring) 1680 { } 1681 else 1682 { 1683 LogRel2(("Too many concurrenct clients for HGCM service '%s': %u, max %u; category %u\n", 1684 m_pszSvcName, m_cClients, m_fntable.acMaxClients[idxClientCategory], idxClientCategory)); 1685 STAM_REL_COUNTER_INC(&m_StatTooManyClients); 1686 return VERR_HGCM_TOO_MANY_CLIENTS; 1687 } 1688 1559 1689 /* Allocate a client information structure. */ 1560 HGCMClient *pClient = new (std::nothrow) HGCMClient(fRequestor );1690 HGCMClient *pClient = new (std::nothrow) HGCMClient(fRequestor, idxClientCategory); 1561 1691 1562 1692 if (!pClient) … … 1633 1763 } 1634 1764 1635 m_paClientIds[m_cClients] = handle; 1636 m_cClients++; 1765 if (RT_SUCCESS(rc)) 1766 { 1767 m_paClientIds[m_cClients] = handle; 1768 m_cClients++; 1769 m_acClients[idxClientCategory]++; 1770 LogFunc(("idClient=%u m_cClients=%u m_acClients[%u]=%u %s\n", 1771 handle, m_cClients, idxClientCategory, m_acClients[idxClientCategory])); 1772 } 1637 1773 } 1638 1774 } 1639 1775 } 1640 1776 1641 if (RT_FAILURE(rc)) 1777 if (RT_SUCCESS(rc)) 1778 { 1779 if (pu32ClientIdOut != NULL) 1780 { 1781 *pu32ClientIdOut = handle; 1782 } 1783 1784 ReferenceService(); 1785 } 1786 else 1642 1787 { 1643 1788 hgcmObjDeleteHandle(handle); 1644 }1645 else1646 {1647 if (pu32ClientIdOut != NULL)1648 {1649 *pu32ClientIdOut = handle;1650 }1651 1652 ReferenceService();1653 1789 } 1654 1790 … … 1678 1814 * for further details. 1679 1815 */ 1816 Assert(pClient->idxCategory < HGCM_CLIENT_CATEGORY_MAX); 1817 Assert(m_acClients[pClient->idxCategory] > 0); 1818 1680 1819 bool fReleaseService = false; 1681 1820 int rc = VERR_NOT_FOUND; … … 1684 1823 if (m_paClientIds[i] == u32ClientId) 1685 1824 { 1825 if (m_acClients[pClient->idxCategory] > 0) 1826 m_acClients[pClient->idxCategory]--; 1827 1686 1828 m_cClients--; 1687 1829 … … 1702 1844 if (rc == VERR_NOT_FOUND && !fFromService) 1703 1845 { 1846 if (m_acClients[pClient->idxCategory] > 0) 1847 m_acClients[pClient->idxCategory]--; 1848 1704 1849 hgcmObjDeleteHandle(u32ClientId); 1705 1850 fReleaseService = true; 1706 1851 } 1852 1853 if (pClient) 1854 LogFunc(("idClient=%u m_cClients=%u m_acClients[%u]=%u %s (cPendingCalls=%u) rc=%Rrc\n", 1855 u32ClientId, m_cClients, pClient->idxCategory, m_acClients[pClient->idxCategory], pClient->cPendingCalls, rc)); 1707 1856 1708 1857 /* … … 1786 1935 } 1787 1936 1937 /** @callback_method_impl{FNHGCMMSGCALLBACK} */ 1938 static DECLCALLBACK(int) hgcmMsgCallCompletionCallback(int32_t result, HGCMMsgCore *pMsgCore) 1939 { 1940 /* 1941 * Do common message completion then decrement the call counter 1942 * for the client if necessary. 1943 */ 1944 int rc = hgcmMsgCompletionCallback(result, pMsgCore); 1945 1946 HGCMMsgCall *pMsg = (HGCMMsgCall *)pMsgCore; 1947 if (pMsg->pcCounter) 1948 { 1949 uint32_t cCalls = ASMAtomicDecU32(pMsg->pcCounter); 1950 AssertStmt(cCalls < UINT32_MAX / 2, ASMAtomicWriteU32(pMsg->pcCounter, 0)); 1951 pMsg->pcCounter = NULL; 1952 Log3Func(("pMsg=%p cPendingCalls=%u / %u (fun %u, %u parms)\n", 1953 pMsg, cCalls, pMsg->u32ClientId, pMsg->u32Function, pMsg->cParms)); 1954 } 1955 1956 return rc; 1957 } 1958 1788 1959 /** Perform a guest call to the service. 1789 1960 * … … 1791 1962 * @param pCmd The VBox HGCM context. 1792 1963 * @param u32ClientId The client handle to be disconnected and deleted. 1964 * @param pClient The client data. 1793 1965 * @param u32Function The function number. 1794 1966 * @param cParms Number of parameters. … … 1798 1970 * @retval VINF_HGCM_ASYNC_EXECUTE on success. 1799 1971 */ 1800 int HGCMService::GuestCall(PPDMIHGCMPORT pHGCMPort, PVBOXHGCMCMD pCmd, uint32_t u32ClientId, uint32_t u32Function,1801 uint32_t cParms, VBOXHGCMSVCPARM paParms[], uint64_t tsArrival)1972 int HGCMService::GuestCall(PPDMIHGCMPORT pHGCMPort, PVBOXHGCMCMD pCmd, uint32_t u32ClientId, HGCMClient *pClient, 1973 uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[], uint64_t tsArrival) 1802 1974 { 1803 1975 LogFlow(("MAIN::HGCMService::GuestCall\n")); 1804 1976 1805 1977 int rc; 1806 HGCMMsgCall *pMsg = new 1978 HGCMMsgCall *pMsg = new(std::nothrow) HGCMMsgCall(m_pThread); 1807 1979 if (pMsg) 1808 1980 { 1809 1981 pMsg->Reference(); /** @todo starts out with zero references. */ 1810 1982 1811 pMsg->pCmd = pCmd; 1812 pMsg->pHGCMPort = pHGCMPort; 1813 pMsg->u32ClientId = u32ClientId; 1814 pMsg->u32Function = u32Function; 1815 pMsg->cParms = cParms; 1816 pMsg->paParms = paParms; 1817 pMsg->tsArrival = tsArrival; 1818 1819 rc = hgcmMsgPost(pMsg, hgcmMsgCompletionCallback); 1983 uint32_t cCalls = ASMAtomicIncU32(&pClient->cPendingCalls); 1984 Assert(pClient->idxCategory < RT_ELEMENTS(m_fntable.acMaxCallsPerClient)); 1985 if (cCalls < m_fntable.acMaxCallsPerClient[pClient->idxCategory]) 1986 { 1987 pMsg->pcCounter = &pClient->cPendingCalls; 1988 Log3(("MAIN::HGCMService::GuestCall: pMsg=%p cPendingCalls=%u / %u / %s (fun %u, %u parms)\n", 1989 pMsg, cCalls, u32ClientId, m_pszSvcName, u32Function, cParms)); 1990 1991 pMsg->pCmd = pCmd; 1992 pMsg->pHGCMPort = pHGCMPort; 1993 pMsg->u32ClientId = u32ClientId; 1994 pMsg->u32Function = u32Function; 1995 pMsg->cParms = cParms; 1996 pMsg->paParms = paParms; 1997 pMsg->tsArrival = tsArrival; 1998 1999 rc = hgcmMsgPost(pMsg, hgcmMsgCallCompletionCallback); 2000 2001 if (RT_SUCCESS(rc)) 2002 { /* Reference donated on success. */ } 2003 else 2004 { 2005 ASMAtomicDecU32(&pClient->cPendingCalls); 2006 pMsg->pcCounter = NULL; 2007 Log(("MAIN::HGCMService::GuestCall: hgcmMsgPost failed: %Rrc\n", rc)); 2008 pMsg->Dereference(); 2009 } 2010 } 2011 else 2012 { 2013 ASMAtomicDecU32(&pClient->cPendingCalls); 2014 LogRel2(("HGCM: Too many calls to '%s' from client %u: %u, max %u; category %u\n", m_pszSvcName, u32ClientId, 2015 cCalls, m_fntable.acMaxCallsPerClient[pClient->idxCategory], pClient->idxCategory)); 2016 pMsg->Dereference(); 2017 STAM_REL_COUNTER_INC(&m_StatTooManyCalls); 2018 rc = VERR_HGCM_TOO_MANY_CLIENT_CALLS; 2019 } 1820 2020 } 1821 2021 else … … 1831 2031 /** Guest cancelled a request (call, connection attempt, disconnect attempt). 1832 2032 * 1833 * @param pHGCMPort The port to be used for completion confirmation .2033 * @param pHGCMPort The port to be used for completion confirmation 1834 2034 * @param pCmd The VBox HGCM context. 1835 2035 * @param idClient The client handle to be disconnected and deleted. … … 2572 2772 2573 2773 /* Forward the message to the service thread. */ 2574 rc = pClient->pService->GuestCall(pHGCMPort, pCmd, u32ClientId, u32Function, cParms, paParms, tsArrival);2774 rc = pClient->pService->GuestCall(pHGCMPort, pCmd, u32ClientId, pClient, u32Function, cParms, paParms, tsArrival); 2575 2775 2576 2776 hgcmObjDereference(pClient);
Note:
See TracChangeset
for help on using the changeset viewer.