DeleteTimerQueueTimer() access violation and/or deadlock

0

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.

c++
windows
visual-c++
windows-7-x64
asked on Stack Overflow Dec 4, 2013 by Oleg B • edited Dec 4, 2013 by Oleg B

1 Answer

2

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.

answered on Stack Overflow Dec 4, 2013 by Werner Henze • edited Dec 4, 2013 by Werner Henze

User contributions licensed under CC BY-SA 3.0