VirtualBox

Changeset 90226 in vbox


Ignore:
Timestamp:
Jul 16, 2021 11:29:21 AM (3 years ago)
Author:
vboxsync
Message:

HGCM: Applied fix for bugref:10038.

Location:
trunk/src/VBox/Main/src-client
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-client/DisplayImpl.cpp

    r90121 r90226  
    1616 */
    1717
     18#ifdef DEBUG_bird               // temporary - bugref:9990
     19# define RTMEM_WRAP_TO_EF_APIS  // temporary - bugref:9990
     20#endif                          // temporary - bugref:9990
    1821#define LOG_GROUP LOG_GROUP_MAIN_DISPLAY
    1922#include "LoggingNew.h"
  • trunk/src/VBox/Main/src-client/HGCM.cpp

    r82968 r90226  
    7272    /* The service name follows. */
    7373};
     74
     75class HGCMClient;
    7476
    7577/** Internal helper service object. HGCM code would use it to
     
    170172
    171173        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);
    173175
    174176        int HostCall(uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM *paParms);
     
    432434{
    433435    public:
    434         /* client identifier */
     436        /** client identifier */
    435437        uint32_t u32ClientId;
     438        /** The client instance. */
     439        HGCMClient *pClient;
    436440};
    437441
     
    632636                HGCMMsgSvcDisconnect *pMsg = (HGCMMsgSvcDisconnect *)pMsgCore;
    633637
    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)
    639641                {
    640642                    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));
    644644                }
    645645                else
     
    868868     HGCMService *pService = static_cast <HGCMService *> (pvInstance);
    869869
     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
    870873     if (pService)
    871874     {
    872          pService->DisconnectClient(u32ClientId, true);
     875         pService->DisconnectClient(u32ClientId, true, NULL);
    873876     }
    874877}
     
    13801383        while (pSvc->m_cClients && pSvc->m_paClientIds)
    13811384        {
    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);
    13841393        }
    13851394
     
    16481657}
    16491658
    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 */
     1669int 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     */
    16611711    if (!fFromService)
    16621712    {
     
    16711721
    16721722            pMsg->u32ClientId = u32ClientId;
     1723            pMsg->pClient = pClient;
    16731724
    16741725            rc = hgcmMsgSend(pMsg);
     
    16811732    }
    16821733
    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();
    17041740
    17051741    LogFlowFunc(("rc = %Rrc\n", rc));
     
    20892125
    20902126                /* Call the service instance to disconnect the client. */
    2091                 rc = pService->DisconnectClient(pMsg->u32ClientId, false);
     2127                rc = pService->DisconnectClient(pMsg->u32ClientId, false, pClient);
    20922128
    20932129                hgcmObjDereference(pClient);
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