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