VirtualBox

Changeset 12324 in vbox for trunk/src


Ignore:
Timestamp:
Sep 10, 2008 5:18:38 AM (16 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
36345
Message:

PDMThread: New API PDMR3ThreadSleep. Fixed a per thread event sem leak.

Location:
trunk/src/VBox/VMM
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/PDMInternal.h

    r11261 r12324  
    246246    /** The VM pointer. */
    247247    PVMR3                           pVM;
    248     /** The event semaphore the thread blocks on. */
     248    /** The event semaphore the thread blocks on when not running. */
    249249    RTSEMEVENTMULTI                 BlockEvent;
     250    /** The event semaphore the thread sleeps on while running. */
     251    RTSEMEVENTMULTI                 SleepEvent;
    250252    /** Pointer to the next thread. */
    251253    R3PTRTYPE(struct PDMTHREAD *)   pNext;
  • trunk/src/VBox/VMM/PDMThread.cpp

    r8155 r12324  
    6262static DECLCALLBACK(int) pdmR3ThreadWakeUp(PPDMTHREAD pThread)
    6363{
     64    RTSemEventMultiSignal(pThread->Internal.s.SleepEvent);
     65
    6466    int rc;
    6567    switch (pThread->Internal.s.enmType)
     
    142144    if (RT_SUCCESS(rc))
    143145    {
    144         /*
    145          * Create the thread and wait for it to initialize.
    146          * The newly created thread will set the PDMTHREAD::Thread member.
    147          */
    148         RTTHREAD Thread;
    149         rc = RTThreadCreate(&Thread, pdmR3ThreadMain, pThread, cbStack, enmType, RTTHREADFLAGS_WAITABLE, pszName);
     146        rc = RTSemEventMultiCreate(&pThread->Internal.s.SleepEvent);
    150147        if (RT_SUCCESS(rc))
    151148        {
    152             rc = RTThreadUserWait(Thread, 60*1000);
    153             if (    RT_SUCCESS(rc)
    154                 &&  pThread->enmState != PDMTHREADSTATE_SUSPENDED)
    155                 rc = VERR_INTERNAL_ERROR;
     149            /*
     150             * Create the thread and wait for it to initialize.
     151             * The newly created thread will set the PDMTHREAD::Thread member.
     152             */
     153            RTTHREAD Thread;
     154            rc = RTThreadCreate(&Thread, pdmR3ThreadMain, pThread, cbStack, enmType, RTTHREADFLAGS_WAITABLE, pszName);
    156155            if (RT_SUCCESS(rc))
    157156            {
    158                 /*
    159                  * Insert it into the thread list.
    160                  */
    161                 pThread->Internal.s.pNext = NULL;
    162                 if (pVM->pdm.s.pThreadsTail)
    163                     pVM->pdm.s.pThreadsTail->Internal.s.pNext = pThread;
    164                 else
    165                     pVM->pdm.s.pThreads = pThread;
    166                 pVM->pdm.s.pThreadsTail = pThread;
    167 
    168                 rc = RTThreadUserReset(Thread);
    169                 AssertRC(rc);
    170                 return rc;
     157                rc = RTThreadUserWait(Thread, 60*1000);
     158                if (    RT_SUCCESS(rc)
     159                    &&  pThread->enmState != PDMTHREADSTATE_SUSPENDED)
     160                    rc = VERR_INTERNAL_ERROR;
     161                if (RT_SUCCESS(rc))
     162                {
     163                    /*
     164                     * Insert it into the thread list.
     165                     */
     166                    pThread->Internal.s.pNext = NULL;
     167                    if (pVM->pdm.s.pThreadsTail)
     168                        pVM->pdm.s.pThreadsTail->Internal.s.pNext = pThread;
     169                    else
     170                        pVM->pdm.s.pThreads = pThread;
     171                    pVM->pdm.s.pThreadsTail = pThread;
     172
     173                    rc = RTThreadUserReset(Thread);
     174                    AssertRC(rc);
     175                    return rc;
     176                }
     177
     178                /* bailout */
     179                RTThreadWait(Thread, 60*1000, NULL);
    171180            }
    172 
    173             /* bailout */
    174             RTThreadWait(Thread, 60*1000, NULL);
     181            RTSemEventMultiDestroy(pThread->Internal.s.SleepEvent);
     182            pThread->Internal.s.SleepEvent = NIL_RTSEMEVENTMULTI;
    175183        }
    176184        RTSemEventMultiDestroy(pThread->Internal.s.BlockEvent);
     
    435443        pThread->Internal.s.pNext = NULL;
    436444
    437         /* free it */
     445        /* free the resources */
     446        RTSemEventMultiDestroy(pThread->Internal.s.BlockEvent);
     447        pThread->Internal.s.BlockEvent = NIL_RTSEMEVENTMULTI;
     448
     449        RTSemEventMultiDestroy(pThread->Internal.s.SleepEvent);
     450        pThread->Internal.s.SleepEvent = NIL_RTSEMEVENTMULTI;
     451
    438452        MMR3HeapFree(pThread);
    439453    }
     
    677691    pdmR3ThreadBailMeOut(pThread);
    678692    return rc;
     693}
     694
     695
     696/**
     697 * Called by the PDM thread instead of RTThreadSleep.
     698 *
     699 * The difference is that the sleep will be interrupted on state change. The
     700 * thread must be in the running state, otherwise it will return immediately.
     701 *
     702 * @returns VBox status code.
     703 * @retval  VINF_SUCCESS on success or state change.
     704 * @retval  VERR_INTERRUPTED on signal or APC.
     705 *
     706 * @param   pThread     The PDM thread.
     707 * @param   cMillies    The number of milliseconds to sleep.
     708 */
     709PDMR3DECL(int) PDMR3ThreadSleep(PPDMTHREAD pThread, unsigned cMillies)
     710{
     711    /*
     712     * Assert sanity.
     713     */
     714    AssertReturn(pThread->enmState > PDMTHREADSTATE_INVALID && pThread->enmState < PDMTHREADSTATE_TERMINATED, VERR_INTERNAL_ERROR);
     715    AssertReturn(pThread->Thread == RTThreadSelf(), VERR_INTERNAL_ERROR);
     716
     717    /*
     718     * Reset the event semaphore, check the state and sleep.
     719     */
     720    RTSemEventMultiReset(pThread->Internal.s.SleepEvent);
     721    if (pThread->enmState != PDMTHREADSTATE_RUNNING)
     722        return VINF_SUCCESS;
     723    return RTSemEventMultiWaitNoResume(pThread->Internal.s.SleepEvent, cMillies);
    679724}
    680725
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