VirtualBox

Changeset 54512 in vbox


Ignore:
Timestamp:
Feb 25, 2015 7:06:07 PM (10 years ago)
Author:
vboxsync
Message:

RTTimerDestroy() is off limits from the timer callback on windows too.

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/timer.h

    r54208 r54512  
    145145 *
    146146 * @returns iprt status code.
     147 * @retval  VERR_WRONG_CONTEXT if executing at the wrong IRQL (windows), PIL
     148 *          (solaris), or similar.  Portable code does not destroy timers with
     149 *          preemption (or interrupts) disabled.
    147150 * @param   pTimer      Timer to stop and destroy. NULL is ok.
    148151 */
  • trunk/src/VBox/Runtime/r0drv/nt/timer-r0drv-nt.cpp

    r53457 r54512  
    3636#include <iprt/asm.h>
    3737#include <iprt/assert.h>
    38 #include <iprt/alloc.h>
     38#include <iprt/mem.h>
     39#include <iprt/thread.h>
    3940
    4041#include "internal-r0drv-nt.h"
     
    5960    /** Pointer to the parent timer. */
    6061    PRTTIMER                pParent;
     62    /** Thread active executing the worker function, NIL if inactive. */
     63    RTNATIVETHREAD volatile hActiveThread;
    6164    /** The NT DPC object. */
    6265    KDPC                    NtDpc;
     
    187190        &&  pTimer->u32Magic == RTTIMER_MAGIC)
    188191    {
     192        ASMAtomicWriteHandle(&pTimer->aSubTimers[0].hActiveThread, RTThreadNativeSelf());
     193
    189194        if (!pTimer->u64NanoInterval)
    190195            ASMAtomicWriteBool(&pTimer->fSuspended, true);
     
    193198            rtTimerNtRearmInternval(pTimer, iTick, &pTimer->aSubTimers[0].NtDpc);
    194199        pTimer->pfnTimer(pTimer, pTimer->pvUser, iTick);
     200
     201        ASMAtomicWriteHandle(&pTimer->aSubTimers[0].hActiveThread, NIL_RTNATIVETHREAD);
    195202    }
    196203
     
    227234        &&  pTimer->u32Magic == RTTIMER_MAGIC)
    228235    {
     236        ASMAtomicWriteHandle(&pSubTimer->hActiveThread, RTThreadNativeSelf());
     237
    229238        if (!pTimer->u64NanoInterval)
    230239            if (ASMAtomicDecS32(&pTimer->cOmniSuspendCountDown) <= 0)
     
    232241
    233242        pTimer->pfnTimer(pTimer, pTimer->pvUser, ++pSubTimer->iTick);
     243
     244        ASMAtomicWriteHandle(&pSubTimer->hActiveThread, NIL_RTNATIVETHREAD);
    234245    }
    235246
     
    272283        RTCPUSET    OnlineSet;
    273284        RTMpGetOnlineSet(&OnlineSet);
     285
     286        ASMAtomicWriteHandle(&pSubTimer->hActiveThread, RTThreadNativeSelf());
    274287
    275288        if (pTimer->u64NanoInterval)
     
    309322            pTimer->pfnTimer(pTimer, pTimer->pvUser, ++pSubTimer->iTick);
    310323        }
     324
     325        ASMAtomicWriteHandle(&pSubTimer->hActiveThread, NIL_RTNATIVETHREAD);
    311326    }
    312327
     
    379394     */
    380395    ASMAtomicWriteBool(&pTimer->fSuspended, true);
     396
    381397    KeCancelTimer(&pTimer->NtTimer);
    382398
    383399    for (RTCPUID iCpu = 0; iCpu < pTimer->cSubTimers; iCpu++)
    384400        KeRemoveQueueDpc(&pTimer->aSubTimers[iCpu].NtDpc);
    385 
    386     /*
    387      * I'm a bit uncertain whether this should be done during RTTimerStop
    388      * or only in RTTimerDestroy()... Linux and Solaris will wait AFAIK,
    389      * which is why I'm keeping this here for now.
    390      */
    391     if (g_pfnrtNtKeFlushQueuedDpcs)
    392         g_pfnrtNtKeFlushQueuedDpcs();
    393401}
    394402
     
    431439
    432440    /*
     441     * We do not support destroying a timer from the callback because it is
     442     * not 101% safe since we cannot flush DPCs.  Solaris has the same restriction.
     443     */
     444    AssertReturn(KeGetCurrentIrql() == PASSIVE_LEVEL, VERR_INVALID_CONTEXT);
     445
     446    /*
    433447     * Invalidate the timer, stop it if it's running and finally
    434448     * free up the memory.
     
    437451    if (!ASMAtomicUoReadBool(&pTimer->fSuspended))
    438452        rtTimerNtStopWorker(pTimer);
     453
     454    /*
     455     * Flush DPCs to be on the safe side.
     456     */
     457    if (g_pfnrtNtKeFlushQueuedDpcs)
     458        g_pfnrtNtKeFlushQueuedDpcs();
     459
    439460    RTMemFree(pTimer);
    440461
  • trunk/src/VBox/Runtime/testcase/tstRTR0Timer.cpp

    r54189 r54512  
    520520#endif
    521521
    522 #if !defined(RT_OS_SOLARIS) /* Not expected to work on all hosts. */
     522#if !defined(RT_OS_SOLARIS) && !defined(RT_OS_WINDOWS) /* Not expected to work on all hosts. */
    523523        case TSTRTR0TIMER_ONE_SHOT_DESTROY:
    524524        case TSTRTR0TIMER_ONE_SHOT_DESTROY_HIRES:
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