Changeset 90228 in vbox
- Timestamp:
- Jul 16, 2021 11:30:51 AM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-client/HGCM.cpp
r90227 r90228 72 72 /* The service name follows. */ 73 73 }; 74 75 class HGCMClient; 74 76 75 77 /** Internal helper service object. HGCM code would use it to … … 170 172 171 173 int CreateAndConnectClient(uint32_t *pu32ClientIdOut, uint32_t u32ClientIdIn, uint32_t fRequestor, bool fRestoring); 172 int DisconnectClient(uint32_t u32ClientId, bool fFromService );174 int DisconnectClient(uint32_t u32ClientId, bool fFromService, HGCMClient *pClient); 173 175 174 176 int HostCall(uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM *paParms); … … 432 434 { 433 435 public: 434 /* client identifier */436 /** client identifier */ 435 437 uint32_t u32ClientId; 438 /** The client instance. */ 439 HGCMClient *pClient; 436 440 }; 437 441 … … 632 636 HGCMMsgSvcDisconnect *pMsg = (HGCMMsgSvcDisconnect *)pMsgCore; 633 637 634 LogFlowFunc(("SVC_MSG_DISCONNECT u32ClientId = %d\n", pMsg->u32ClientId)); 635 636 HGCMClient *pClient = (HGCMClient *)hgcmObjReference(pMsg->u32ClientId, HGCMOBJ_CLIENT); 637 638 if (pClient) 638 LogFlowFunc(("SVC_MSG_DISCONNECT u32ClientId = %d, pClient = %p\n", pMsg->u32ClientId, pMsg->pClient)); 639 640 if (pMsg->pClient) 639 641 { 640 642 rc = pSvc->m_fntable.pfnDisconnect(pSvc->m_fntable.pvService, pMsg->u32ClientId, 641 HGCM_CLIENT_DATA(pSvc, pClient)); 642 643 hgcmObjDereference(pClient); 643 HGCM_CLIENT_DATA(pSvc, pMsg->pClient)); 644 644 } 645 645 else … … 868 868 HGCMService *pService = static_cast <HGCMService *> (pvInstance); 869 869 870 AssertMsgFailed(("This is unused code with a serialization issue.\n" 871 "It touches data which is normally serialized by only running on the HGCM thread!\n")); 872 870 873 if (pService) 871 874 { 872 pService->DisconnectClient(u32ClientId, true );875 pService->DisconnectClient(u32ClientId, true, NULL); 873 876 } 874 877 } … … 1380 1383 while (pSvc->m_cClients && pSvc->m_paClientIds) 1381 1384 { 1382 LogFlowFunc(("handle %d\n", pSvc->m_paClientIds[0])); 1383 pSvc->DisconnectClient(pSvc->m_paClientIds[0], false); 1385 uint32_t const idClient = pSvc->m_paClientIds[0]; 1386 HGCMClient * const pClient = (HGCMClient *)hgcmObjReference(idClient, HGCMOBJ_CLIENT); 1387 Assert(pClient); 1388 LogFlowFunc(("handle %d/%p\n", pSvc->m_paClientIds[0], pClient)); 1389 1390 pSvc->DisconnectClient(pSvc->m_paClientIds[0], false, pClient); 1391 1392 hgcmObjDereference(pClient); 1384 1393 } 1385 1394 … … 1648 1657 } 1649 1658 1650 /* Disconnect the client from the service and delete the client handle. 1651 * 1652 * @param u32ClientId The handle of the client. 1653 * @return VBox rc. 1654 */ 1655 int HGCMService::DisconnectClient(uint32_t u32ClientId, bool fFromService) 1656 { 1657 int rc = VINF_SUCCESS; 1658 1659 LogFlowFunc(("client id = %d, fFromService = %d\n", u32ClientId, fFromService)); 1660 1659 /** 1660 * Disconnect the client from the service and delete the client handle. 1661 * 1662 * @param u32ClientId The handle of the client. 1663 * @param fFromService Set if called by the service via 1664 * svcHlpDisconnectClient(). pClient can be NULL when 1665 * this is @c true. 1666 * @param pClient The client disconnecting. NULL if from service. 1667 * @return VBox status code. 1668 */ 1669 int HGCMService::DisconnectClient(uint32_t u32ClientId, bool fFromService, HGCMClient *pClient) 1670 { 1671 Assert(pClient || !fFromService); 1672 1673 LogFlowFunc(("client id = %d, fFromService = %d, pClient = %p\n", u32ClientId, fFromService, pClient)); 1674 1675 /* 1676 * Destroy the client handle prior to the disconnecting to avoid creating 1677 * a race with other messages from the same client. See @bugref{10038} 1678 * for further details. 1679 */ 1680 bool fReleaseService = false; 1681 int rc = VERR_NOT_FOUND; 1682 for (uint32_t i = 0; i < m_cClients; i++) 1683 { 1684 if (m_paClientIds[i] == u32ClientId) 1685 { 1686 m_cClients--; 1687 1688 if (m_cClients > i) 1689 memmove(&m_paClientIds[i], &m_paClientIds[i + 1], sizeof(m_paClientIds[0]) * (m_cClients - i)); 1690 1691 /* Delete the client handle. */ 1692 hgcmObjDeleteHandle(u32ClientId); 1693 fReleaseService = true; 1694 1695 rc = VINF_SUCCESS; 1696 break; 1697 } 1698 } 1699 1700 /* Some paranoia wrt to not trusting the client ID array. */ 1701 Assert(rc == VINF_SUCCESS || fFromService); 1702 if (rc == VERR_NOT_FOUND && !fFromService) 1703 { 1704 hgcmObjDeleteHandle(u32ClientId); 1705 fReleaseService = true; 1706 } 1707 1708 /* 1709 * Call the service. 1710 */ 1661 1711 if (!fFromService) 1662 1712 { … … 1671 1721 1672 1722 pMsg->u32ClientId = u32ClientId; 1723 pMsg->pClient = pClient; 1673 1724 1674 1725 rc = hgcmMsgSend(pMsg); … … 1681 1732 } 1682 1733 1683 /* Remove the client id from the array in any case, rc does not matter. */ 1684 uint32_t i; 1685 1686 for (i = 0; i < m_cClients; i++) 1687 { 1688 if (m_paClientIds[i] == u32ClientId) 1689 { 1690 m_cClients--; 1691 1692 if (m_cClients > i) 1693 memmove(&m_paClientIds[i], &m_paClientIds[i + 1], sizeof(m_paClientIds[0]) * (m_cClients - i)); 1694 1695 /* Delete the client handle. */ 1696 hgcmObjDeleteHandle(u32ClientId); 1697 1698 /* The service must be released. */ 1699 ReleaseService(); 1700 1701 break; 1702 } 1703 } 1734 1735 /* 1736 * Release the pClient->pService reference. 1737 */ 1738 if (fReleaseService) 1739 ReleaseService(); 1704 1740 1705 1741 LogFlowFunc(("rc = %Rrc\n", rc)); … … 2089 2125 2090 2126 /* Call the service instance to disconnect the client. */ 2091 rc = pService->DisconnectClient(pMsg->u32ClientId, false );2127 rc = pService->DisconnectClient(pMsg->u32ClientId, false, pClient); 2092 2128 2093 2129 hgcmObjDereference(pClient);
Note:
See TracChangeset
for help on using the changeset viewer.