VirtualBox

Changeset 50039 in vbox for trunk/src/VBox/Additions


Ignore:
Timestamp:
Jan 9, 2014 3:24:47 PM (11 years ago)
Author:
vboxsync
Message:

VBoxTray/IPC: Fixed handle leaks.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxIPC.cpp

    r49378 r50039  
    77
    88/*
    9  * Copyright (C) 2010-2013 Oracle Corporation
     9 * Copyright (C) 2010-2014 Oracle Corporation
    1010 *
    1111 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    7878static PFNGETLASTINPUTINFO s_pfnGetLastInputInfo = NULL;
    7979
    80 int vboxIPCSessionDestroyLocked(PVBOXIPCSESSION pSession);
     80int vboxIPCSessionStop(PVBOXIPCSESSION pSession);
    8181
    8282static int vboxIPCHandleVBoxTrayRestart(PVBOXIPCSESSION pSession, PVBOXTRAYIPCHEADER pHdr)
     
    231231    LogFunc(("Stopping pInstance=%p\n", pInstance));
    232232
     233    /* Shut down local IPC server. */
    233234    PVBOXIPCCONTEXT pCtx = (PVBOXIPCCONTEXT)pInstance;
    234235    AssertPtr(pCtx);
     
    240241            LogFunc(("Cancelling current listening call failed with rc=%Rrc\n", rc2));
    241242    }
     243
     244    /* Stop all remaining session threads. */
     245    int rc = RTCritSectEnter(&pCtx->CritSect);
     246    if (RT_SUCCESS(rc))
     247    {
     248        PVBOXIPCSESSION pSession;
     249        RTListForEach(&pCtx->SessionList, pSession, VBOXIPCSESSION, Node)
     250        {
     251            int rc2 = vboxIPCSessionStop(pSession);
     252            if (RT_FAILURE(rc2))
     253            {
     254                LogFunc(("Stopping IPC session %p failed with rc=%Rrc\n",
     255                         pSession, rc2));
     256                /* Keep going. */
     257            }
     258        }
     259    }
    242260}
    243261
    244262void VBoxIPCDestroy(const VBOXSERVICEENV *pEnv, void *pInstance)
    245263{
    246     AssertPtr(pEnv);
    247     AssertPtr(pInstance);
     264    AssertPtrReturnVoid(pEnv);
     265    AssertPtrReturnVoid(pInstance);
    248266
    249267    LogFunc(("Destroying pInstance=%p\n", pInstance));
     
    252270    AssertPtr(pCtx);
    253271
     272    /* Shut down local IPC server. */
    254273    int rc = RTCritSectEnter(&pCtx->CritSect);
    255274    if (RT_SUCCESS(rc))
    256275    {
    257         PVBOXIPCSESSION pSession;
    258         RTListForEach(&pCtx->SessionList, pSession, VBOXIPCSESSION, Node)
    259         {
    260             int rc2 = vboxIPCSessionDestroyLocked(pSession);
    261             if (RT_FAILURE(rc2))
    262             {
    263                 LogFunc(("Destroying IPC session %p failed with rc=%Rrc\n",
    264                          pSession, rc2));
    265                 /* Keep going. */
    266             }
    267         }
    268 
    269         RTLocalIpcServerDestroy(pCtx->hServer);
     276        rc = RTLocalIpcServerDestroy(pCtx->hServer);
     277        if (RT_FAILURE(rc))
     278            LogFunc(("Unable to destroy IPC server, rc=%Rrc\n", rc));
    270279
    271280        int rc2 = RTCritSectLeave(&pCtx->CritSect);
    272         AssertRC(rc2);
    273 
    274         rc2 = RTCritSectDelete(&pCtx->CritSect);
    275         AssertRC(rc2);
    276     }
     281        if (RT_SUCCESS(rc))
     282            rc = rc2;
     283    }
     284
     285    LogFunc(("Waiting for remaining IPC sessions to shut down ...\n"));
     286
     287    /* Wait for all IPC session threads to shut down. */
     288    bool fListIsEmpty = true;
     289    do
     290    {
     291        int rc2 = RTCritSectEnter(&pCtx->CritSect);
     292        if (RT_SUCCESS(rc2))
     293        {
     294            fListIsEmpty = RTListIsEmpty(&pCtx->SessionList);
     295            rc2 = RTCritSectLeave(&pCtx->CritSect);
     296        }
     297
     298        if (RT_FAILURE(rc2))
     299            break;
     300
     301    } while (!fListIsEmpty);
     302
     303    AssertMsg(fListIsEmpty,
     304              ("Session thread list is not empty when it should\n"));
     305
     306    LogFunc(("All remaining IPC sessions shut down\n"));
     307
     308    int rc2 = RTCritSectDelete(&pCtx->CritSect);
     309    if (RT_SUCCESS(rc))
     310        rc = rc2;
    277311
    278312    LogFunc(("Destroyed pInstance=%p, rc=%Rrc\n",
     
    390424
    391425    /*
     426     * Close the session.
     427     */
     428    int rc2 = RTLocalIpcSessionClose(hSession);
     429    if (RT_FAILURE(rc2))
     430        LogFunc(("Session %p: Failed closing session %p, rc=%Rrc\n", pThis, rc2));
     431
     432    /*
    392433     * Clean up the session.
    393434     */
    394435    PVBOXIPCCONTEXT pCtx = ASMAtomicReadPtrT(&pThis->pCtx, PVBOXIPCCONTEXT);
    395436    AssertMsg(pCtx, ("Session %p: No context found\n", pThis));
    396     rc = RTCritSectEnter(&pCtx->CritSect);
    397     if (RT_SUCCESS(rc))
    398     {
    399         rc = vboxIPCSessionDestroyLocked(pThis);
    400 
    401         int rc2 = RTCritSectLeave(&pCtx->CritSect);
     437    rc2 = RTCritSectEnter(&pCtx->CritSect);
     438    if (RT_SUCCESS(rc2))
     439    {
     440        /* Remove this session from the session list. */
     441        RTListNodeRemove(&pThis->Node);
     442
     443        rc2 = RTCritSectLeave(&pCtx->CritSect);
    402444        if (RT_SUCCESS(rc))
    403445            rc = rc2;
    404446    }
    405447
    406     LogFunc(("Session %p: Terminated\n", pThis));
     448    LogFunc(("Session %p: Terminated with rc=%Rrc, freeing ...\n",
     449             pThis, rc));
     450
     451    RTMemFree(pThis);
     452    pThis = NULL;
     453
    407454    return rc;
    408455}
     
    426473            /* Start IPC session thread. */
    427474            LogFlowFunc(("Creating thread for session %p ...\n", pSession));
    428             rc = RTThreadCreate(&pSession->hThread, vboxIPCSessionThread, pSession, 0,
    429                                 RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "VBXTRYIPCSESS");
     475            rc = RTThreadCreate(&pSession->hThread, vboxIPCSessionThread,
     476                                pSession /* pvUser */, 0 /* Default stack size */,
     477                                RTTHREADTYPE_DEFAULT, 0 /* Flags */, "VBXTRYIPCSESS");
    430478            if (RT_SUCCESS(rc))
    431479            {
     
    453501}
    454502
    455 static int vboxIPCSessionDestroyLocked(PVBOXIPCSESSION pSession)
     503static int vboxIPCSessionStop(PVBOXIPCSESSION pSession)
    456504{
    457505    AssertPtrReturn(pSession, VERR_INVALID_POINTER);
    458506
    459     pSession->hThread = NIL_RTTHREAD;
     507    ASMAtomicWriteBool(&pSession->fTerminate, true);
    460508
    461509    RTLOCALIPCSESSION hSession;
    462510    ASMAtomicXchgHandle(&pSession->hSession, NIL_RTLOCALIPCSESSION, &hSession);
    463     int rc = RTLocalIpcSessionClose(hSession);
    464 
    465     RTListNodeRemove(&pSession->Node);
    466 
    467     RTMemFree(pSession);
    468     pSession = NULL;
    469 
    470     return rc;
     511    if (hSession)
     512        return RTLocalIpcSessionClose(hSession);
     513
     514    return VINF_SUCCESS;
    471515}
    472516
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