Second DeleteTimerQueueTimer() generates access violation, or invalid parameter exception, or hangs indefinetely, depending on context. Google test code:
HANDLE hTimer = NULL;
static VOID CALLBACK _TimerCallback(PVOID, BOOLEAN)
{
//::DeleteTimerQueueTimer(NULL, hTimer, NULL);
}
TEST(CTest, TimerQueue)
{
ASSERT_EQ(FALSE, ::DeleteTimerQueueTimer(NULL, hTimer, NULL));
ASSERT_EQ(TRUE, ::CreateTimerQueueTimer(&hTimer, NULL, &_TimerCallback, NULL, 40, 0, WT_EXECUTEONLYONCE));
ASSERT_TRUE(NULL != hTimer);
Sleep(100);
ASSERT_EQ(TRUE, ::DeleteTimerQueueTimer(NULL, hTimer, NULL));
// ******** next line produces SEH or deadlocks *************
ASSERT_EQ(FALSE, ::DeleteTimerQueueTimer(NULL, hTimer, NULL));
}
[ RUN ] CTest.TimerQueue unknown file: error: SEH exception with code 0xc000000d thrown in the test body.
MSDN says: "Timer [in]: A handle to the timer-queue timer. This handle is returned by the CreateTimerQueueTimer function."
You are calling DeleteTimerQueueTimer
twice for the same hTimer
. So in the second call to DeleteTimerQueueTimer
you are not adhering to the function specification because you are passing some invalid HANDLE
. Windows might (in my opinion should) handle that in a better way than with an SEH or hanging but: garbage in, garbage out.
User contributions licensed under CC BY-SA 3.0