RTDECL(int) RTTimerDestroy(PRTTIMER pTimer) { /* It's ok to pass NULL pointer. */ if (pTimer == /*NIL_RTTIMER*/ NULL) return VINF_SUCCESS; AssertPtrReturn(pTimer, VERR_INVALID_HANDLE); AssertReturn(pTimer->u32Magic == RTTIMER_MAGIC, VERR_INVALID_HANDLE); /* * We do not support destroying a timer from the callback because it is * not 101% safe since we cannot flush DPCs. Solaris has the same restriction. */ AssertReturn(KeGetCurrentIrql() == PASSIVE_LEVEL, VERR_INVALID_CONTEXT); /* * Invalidate the timer, stop it if it's running and finally * free up the memory. */ ASMAtomicWriteU32(&pTimer->u32Magic, ~RTTIMER_MAGIC); if (!ASMAtomicUoReadBool(&pTimer->fSuspended)) rtTimerNtStopWorker(pTimer); /* * Flush DPCs to be on the safe side. */ if (g_pfnrtNtKeFlushQueuedDpcs) g_pfnrtNtKeFlushQueuedDpcs(); RTMemFree(pTimer); return VINF_SUCCESS; }
RTDECL(int) RTTimerStop(PRTTIMER pTimer) { /* * Validate. */ AssertPtrReturn(pTimer, VERR_INVALID_HANDLE); AssertReturn(pTimer->u32Magic == RTTIMER_MAGIC, VERR_INVALID_HANDLE); if (ASMAtomicUoReadBool(&pTimer->fSuspended)) return VERR_TIMER_SUSPENDED; /* * Call the worker we share with RTTimerDestroy. */ rtTimerNtStopWorker(pTimer); return VINF_SUCCESS; }
RTDECL(int) RTTimerDestroy(PRTTIMER pTimer) { /* It's ok to pass NULL pointer. */ if (pTimer == /*NIL_RTTIMER*/ NULL) return VINF_SUCCESS; AssertPtrReturn(pTimer, VERR_INVALID_HANDLE); AssertReturn(pTimer->u32Magic == RTTIMER_MAGIC, VERR_INVALID_HANDLE); /* * Invalidate the timer, stop it if it's running and finally * free up the memory. */ ASMAtomicWriteU32(&pTimer->u32Magic, ~RTTIMER_MAGIC); if (!ASMAtomicUoReadBool(&pTimer->fSuspended)) rtTimerNtStopWorker(pTimer); RTMemFree(pTimer); return VINF_SUCCESS; }