VirtualBox

Changeset 6981 in vbox for trunk/src/VBox/Main


Ignore:
Timestamp:
Feb 18, 2008 10:05:36 AM (17 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
28172
Message:

HostServices/SharedClipboard: attempt to handle the guest reconnecting without first disconnecting more gracefully

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/hgcm/HGCM.cpp

    r6967 r6981  
    9797        char *m_pszSvcName;
    9898        char *m_pszSvcLibrary;
    99 
     99       
    100100        RTLDRMOD m_hLdrMod;
    101101        PFNVBOXHGCMSVCLOAD m_pfnLoad;
     
    107107
    108108        uint32_t *m_paClientIds;
    109 
     109       
    110110        HGCMSVCEXTHANDLE m_hExtension;
    111111
     
    126126
    127127        static DECLCALLBACK(void) svcHlpCallComplete (VBOXHGCMCALLHANDLE callHandle, int32_t rc);
    128 
     128        static DECLCALLBACK(void) svcHlpDisconnectClient (void *pvInstance, uint32_t u32ClientId);
     129       
    129130    public:
    130131
     
    147148
    148149        int CreateAndConnectClient (uint32_t *pu32ClientIdOut, uint32_t u32ClientIdIn);
    149         int DisconnectClient (uint32_t u32ClientId);
     150        int DisconnectClient (uint32_t u32ClientId, bool fFromService);
    150151
    151152        int HostCall (uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM *paParms);
     
    239240     * If only library name is specified, then try to load it from:
    240241     *   - RTPathAppPrivateArch
    241      *   - RTPathSharedLibs (legacy)
     242     *   - RTPathSharedLibs
     243     *   - default system LIBPATH.
    242244     */
    243245    int rc = VINF_SUCCESS;
    244 
     246   
    245247    if (RTPathHavePath (pszName))
    246248    {
     
    250252    else
    251253    {
     254        if (strlen (pszName) >= RTPATH_MAX)
     255        {
     256            return VERR_FILENAME_TOO_LONG;
     257        }
     258   
    252259        /* Try default locations. */
    253260        char szBase[RTPATH_MAX];
    254 
     261       
    255262        /* Get the appropriate base path. */
    256263        int i;
    257         for (i = 0; i < 2; i++)
     264        for (i = 0; i < 3; i++)
    258265        {
    259266            if (i == 0)
     
    261268                rc = RTPathAppPrivateArch(szBase, sizeof (szBase));
    262269            }
    263             else
     270            else if (i == 1)
    264271            {
    265272                rc = RTPathSharedLibs(szBase, sizeof (szBase));
    266273            }
    267 
     274            else
     275            {
     276                szBase[0] = 0;
     277                rc = VINF_SUCCESS;
     278            }
     279           
    268280            if (RT_SUCCESS(rc))
    269281            {
    270282                char szPath[RTPATH_MAX];
    271 
     283       
    272284                /* szPath = pszBase + pszName */
    273                 rc = RTPathAbsEx (szBase, pszName, szPath, sizeof (szPath));
    274 
     285                if (szBase[0] != 0)
     286                {
     287                    rc = RTPathAbsEx (szBase, pszName, szPath, sizeof (szPath));
     288                }
     289                else
     290                {
     291                    strcpy (szPath, pszName);
     292                }
     293           
    275294                if (RT_SUCCESS(rc))
    276295                {
    277296                    rc = RTLdrLoad (szPath, phLdrMod);
    278 
     297           
    279298                    if (RT_SUCCESS(rc))
    280299                    {
     
    286305        }
    287306    }
    288 
     307   
    289308    return rc;
    290309}
     
    430449    public:
    431450        HGCMMsgHeader () : pCmd (NULL), pHGCMPort (NULL) {};
    432 
     451       
    433452        /* Command pointer/identifier. */
    434453        PVBOXHGCMCMD pCmd;
     
    501520        case SVC_MSG_HOSTCALL:    return new HGCMMsgHostCallSvc ();
    502521        case SVC_MSG_GUESTCALL:   return new HGCMMsgCall ();
    503         case SVC_MSG_LOADSTATE:
     522        case SVC_MSG_LOADSTATE:     
    504523        case SVC_MSG_SAVESTATE:   return new HGCMMsgLoadSaveStateClient ();
    505524        case SVC_MSG_REGEXT:      return new HGCMMsgSvcRegisterExtension ();
     
    676695                }
    677696            } break;
    678 
     697           
    679698            case SVC_MSG_REGEXT:
    680699            {
     
    682701
    683702                LogFlowFunc(("SVC_MSG_REGEXT handle = %p, pfn = %p\n", pMsg->handle, pMsg->pfnExtension));
    684 
     703               
    685704                if (pSvc->m_hExtension)
    686705                {
     
    697716                        rc = VERR_NOT_SUPPORTED;
    698717                    }
    699 
     718                   
    700719                    if (VBOX_SUCCESS (rc))
    701720                    {
     
    710729
    711730                LogFlowFunc(("SVC_MSG_UNREGEXT handle = %p\n", pMsg->handle));
    712 
     731               
    713732                if (pSvc->m_hExtension != pMsg->handle)
    714733                {
     
    725744                        rc = VERR_NOT_SUPPORTED;
    726745                    }
    727 
     746                   
    728747                    pSvc->m_hExtension = NULL;
    729748                }
     
    753772   if (pMsgCore->MsgId () == SVC_MSG_GUESTCALL)
    754773   {
    755        /* Only call the completion for these messages. The helper
     774       /* Only call the completion for these messages. The helper 
    756775        * is called by the service, and the service does not get
    757776        * any other messages.
     
    765784}
    766785
     786/* static */ DECLCALLBACK(void) HGCMService::svcHlpDisconnectClient (void *pvInstance, uint32_t u32ClientId)
     787{
     788     HGCMService *pService = static_cast <HGCMService *> (pvInstance);
     789     
     790     if (pService)
     791     {
     792         pService->DisconnectClient (u32ClientId, true);
     793     }
     794}
     795
    767796static DECLCALLBACK(void) hgcmMsgCompletionCallback (int32_t result, HGCMMsgCore *pMsgCore)
    768797{
     
    803832            RTStrFree (m_pszSvcLibrary);
    804833            m_pszSvcLibrary = NULL;
    805 
     834           
    806835            RTStrFree (m_pszSvcName);
    807836            m_pszSvcName = NULL;
    808 
     837           
    809838            rc = VERR_NO_MEMORY;
    810839        }
     
    812841        {
    813842            /* Initialize service helpers table. */
    814             m_svcHelpers.pfnCallComplete = svcHlpCallComplete;
    815             m_svcHelpers.pvInstance      = this;
    816 
     843            m_svcHelpers.pfnCallComplete     = svcHlpCallComplete;
     844            m_svcHelpers.pvInstance          = this;
     845            m_svcHelpers.pfnDisconnectClient = svcHlpDisconnectClient;
     846           
    817847            /* Execute the load request on the service thread. */
    818848            HGCMMSGHANDLE hMsg;
     
    924954    HGCMService *pSvc;
    925955    int rc = HGCMService::ResolveService (&pSvc, pszServiceName);
    926 
     956   
    927957    if (VBOX_SUCCESS (rc))
    928958    {
     
    950980                pSvc->m_pSvcNext = sm_pSvcListHead;
    951981                pSvc->m_pSvcPrev = NULL;
    952 
     982               
    953983                if (sm_pSvcListHead)
    954984                {
     
    10791109    ASMAtomicIncU32 (&m_u32RefCnt);
    10801110    LogFlowFunc(("m_u32RefCnt = %d\n", m_u32RefCnt));
    1081 }
     1111}       
    10821112
    10831113/** The method dereferences a service and deletes it when no more refs.
     
    11161146        {
    11171147            LogFlowFunc(("handle %d\n", pSvc->m_paClientIds[0]));
    1118             pSvc->DisconnectClient (pSvc->m_paClientIds[0]);
     1148            pSvc->DisconnectClient (pSvc->m_paClientIds[0], false);
    11191149        }
    11201150
     
    11381168
    11391169    LogFlowFunc(("%d services to be saved:\n", sm_cServices));
    1140 
     1170   
    11411171    /* Save number of services. */
    11421172    rc = SSMR3PutU32(pSSM, sm_cServices);
     
    12101240    rc = SSMR3GetU32(pSSM, &cServices);
    12111241    AssertRCReturn(rc, rc);
    1212 
     1242   
    12131243    LogFlowFunc(("%d services to be restored:\n", cServices));
    12141244
     
    12191249        AssertRCReturn(rc, rc);
    12201250        AssertReturn(u32 <= VBOX_HGCM_SVC_NAME_MAX_BYTES, VERR_SSM_UNEXPECTED_DATA);
    1221 
     1251       
    12221252        char *pszServiceName = (char *)alloca (u32);
    12231253
     
    12251255        rc = SSMR3GetStrZ(pSSM, pszServiceName, u32);
    12261256        AssertRCReturn(rc, rc);
    1227 
     1257       
    12281258        LogFlowFunc(("Restoring service [%s]\n", pszServiceName));
    1229 
     1259   
    12301260        /* Resolve the service instance. */
    1231         HGCMService *pSvc;
     1261        HGCMService *pSvc; 
    12321262        rc = ResolveService (&pSvc, pszServiceName);
    12331263        AssertReturn(pSvc, VERR_SSM_UNEXPECTED_DATA);
    1234 
     1264           
    12351265        /* Get the number of clients. */
    12361266        uint32_t cClients;
     
    13011331
    13021332    uint32_t handle;
    1303 
     1333   
    13041334    if (pu32ClientIdOut != NULL)
    13051335    {
     
    13351365
    13361366            rc = hgcmMsgSend (hMsg);
    1337 
     1367       
    13381368            if (VBOX_SUCCESS (rc))
    13391369            {
     
    13451375                    m_cClientsAllocated += 64;
    13461376                }
    1347 
     1377           
    13481378                m_paClientIds[m_cClients] = handle;
    13491379                m_cClients++;
     
    13651395        ReferenceService ();
    13661396    }
    1367 
     1397   
    13681398    LogFlowFunc(("rc = %Vrc\n", rc));
    13691399    return rc;
     
    13751405 * @return VBox rc.
    13761406 */
    1377 int HGCMService::DisconnectClient (uint32_t u32ClientId)
    1378 {
    1379     LogFlowFunc(("client id = %d\n", u32ClientId));
    1380 
    1381     /* Call the service. */
    1382     HGCMMSGHANDLE hMsg;
    1383 
    1384     int rc = hgcmMsgAlloc (m_thread, &hMsg, SVC_MSG_DISCONNECT, hgcmMessageAllocSvc);
    1385 
    1386     if (VBOX_SUCCESS(rc))
    1387     {
    1388         HGCMMsgSvcDisconnect *pMsg = (HGCMMsgSvcDisconnect *)hgcmObjReference (hMsg, HGCMOBJ_MSG);
    1389         AssertRelease(pMsg);
    1390 
    1391         pMsg->u32ClientId = u32ClientId;
    1392 
    1393         hgcmObjDereference (pMsg);
    1394 
    1395         rc = hgcmMsgSend (hMsg);
    1396 
     1407int HGCMService::DisconnectClient (uint32_t u32ClientId, bool fFromService)
     1408{
     1409    int rc = VINF_SUCCESS;
     1410
     1411    LogFlowFunc(("client id = %d, fFromService = %d\n", u32ClientId, fFromService));
     1412
     1413    if (!fFromService)
     1414    {
     1415        /* Call the service. */
     1416        HGCMMSGHANDLE hMsg;
     1417
     1418        rc = hgcmMsgAlloc (m_thread, &hMsg, SVC_MSG_DISCONNECT, hgcmMessageAllocSvc);
     1419
     1420        if (VBOX_SUCCESS(rc))
     1421        {
     1422            HGCMMsgSvcDisconnect *pMsg = (HGCMMsgSvcDisconnect *)hgcmObjReference (hMsg, HGCMOBJ_MSG);
     1423            AssertRelease(pMsg);
     1424
     1425            pMsg->u32ClientId = u32ClientId;
     1426
     1427            hgcmObjDereference (pMsg);
     1428
     1429            rc = hgcmMsgSend (hMsg);
     1430        }
     1431    }
     1432
     1433    if (VBOX_SUCCESS (rc))
     1434    {
    13971435        /* Remove the client id from the array in any case. */
    13981436        int i;
     
    14031441            {
    14041442                m_cClients--;
    1405 
     1443               
    14061444                if (m_cClients > i)
    14071445                {
    14081446                    memmove (&m_paClientIds[i], &m_paClientIds[i + 1], m_cClients - i);
    14091447                }
    1410 
     1448               
    14111449                break;
    14121450            }
     
    15521590
    15531591
    1554 /*
     1592/* 
    15551593 * Main HGCM thread that manages services.
    15561594 */
    1557 
     1595 
    15581596/* Messages processed by the main HGCM thread. */
    15591597#define HGCM_MSG_CONNECT    (10)  /* Connect a client to a service. */
     
    16491687        case HGCM_MSG_LOAD:       return new HGCMMsgMainLoad ();
    16501688        case HGCM_MSG_HOSTCALL:   return new HGCMMsgMainHostCall ();
    1651         case HGCM_MSG_LOADSTATE:
     1689        case HGCM_MSG_LOADSTATE:     
    16521690        case HGCM_MSG_SAVESTATE:  return new HGCMMsgMainLoadSaveState ();
    16531691        case HGCM_MSG_RESET:      return new HGCMMsgMainReset ();
     
    17301768
    17311769                /* Call the service instance to disconnect the client. */
    1732                 rc = pService->DisconnectClient (pMsg->u32ClientId);
     1770                rc = pService->DisconnectClient (pMsg->u32ClientId, false);
    17331771
    17341772                hgcmObjDereference (pClient);
     
    18011839            {
    18021840                HGCMMsgMainRegisterExtension *pMsg = (HGCMMsgMainRegisterExtension *)pMsgCore;
    1803 
     1841               
    18041842                LogFlowFunc(("HGCM_MSG_REGEXT\n"));
    1805 
     1843               
    18061844                /* Allocate the handle data. */
    18071845                HGCMSVCEXTHANDLE handle = (HGCMSVCEXTHANDLE)RTMemAllocZ (sizeof (struct _HGCMSVCEXTHANDLEDATA)
    18081846                                                                         + strlen (pMsg->pszServiceName)
    18091847                                                                         + sizeof (char));
    1810 
     1848               
    18111849                if (handle == NULL)
    18121850                {
     
    18171855                    handle->pszServiceName = (char *)((uint8_t *)handle + sizeof (struct _HGCMSVCEXTHANDLEDATA));
    18181856                    strcpy (handle->pszServiceName, pMsg->pszServiceName);
    1819 
     1857                   
    18201858                    HGCMService *pService;
    18211859                    rc = HGCMService::ResolveService (&pService, handle->pszServiceName);
     
    18271865                        pService->ReleaseService ();
    18281866                    }
    1829 
     1867                   
    18301868                    if (VBOX_FAILURE (rc))
    18311869                    {
     
    18541892                    pService->ReleaseService ();
    18551893                }
    1856 
     1894               
    18571895                RTMemFree (pMsg->handle);
    18581896            } break;
     
    22192257        HGCMMsgMainHostCall *pMsg = (HGCMMsgMainHostCall *)hgcmObjReference (hMsg, HGCMOBJ_MSG);
    22202258        AssertRelease(pMsg);
    2221 
     2259       
    22222260        pMsg->pszServiceName = (char *)pszServiceName;
    22232261        pMsg->u32Function    = u32Function;
     
    22372275{
    22382276    LogFlowFunc(("\n"));
    2239 
     2277   
    22402278    /* Disconnect all clients.
    22412279     */
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette