how can i use the CreateTimerQueueTimer()?

Started by
21 comments, last by cambalinho 7 years, 11 months ago

heres how i use the CreateTimerQueueTimer():


class Timer
{

private:
    static unsigned int TimerCount;
    PHANDLE m_timerHandle=NULL;
    UINT_PTR timerid;
    UINT m_uResolution=0;
    unsigned int TimerID=0;
    unsigned int intInterval=0;

    static void CALLBACK TimerProc(void* InstancePointer, BOOLEAN TimerOrWaitFired)
    {
        Timer* obj=reinterpret_cast<Timer*>(InstancePointer);
        if(obj->timerprocedure!=nullptr)
            obj->timerprocedure();
    }

public:

    std::function<void()> timerprocedure=EmptyEvent;
    Timer(std::function<void()> tmrprocedure=EmptyEvent)
    {
        TimerCount++;
        TimerID=TimerCount-1;
        timerprocedure=tmrprocedure;
    }

    void Stop()
    {
        DeleteTimerQueueTimer(NULL, m_timerHandle, NULL);
        CloseHandle (m_timerHandle);
    }

    unsigned int GetInterval()
    {
        return intInterval;
    }

    void SetInterval(unsigned int uintInterval)
    {
        intInterval = uintInterval;
    }

    property <unsigned int> Interval{GetProperty(Timer::GetInterval),SetProperty(Timer::SetInterval)};

    void Start()
    {
        if(m_timerHandle!=0)
            Stop();
        if (CreateTimerQueueTimer(m_timerHandle,NULL,TimerProc,reinterpret_cast<PVOID>(this),0,(DWORD)intInterval ,WT_EXECUTEINTIMERTHREAD)==0)
            DebugText("error\t" + to_string(GetLastError()));
    }

    ~Timer()
    {
        if(m_timerHandle!=0)
            Stop();
    }
};
unsigned int Timer::TimerCount=0;

for now, i only get a memory leak... so what i'm doing wrong?

Advertisement
Start with the documentation. In particular your interpretation of the return value is wrong.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

i did 1 change, the m_timerHandle is now HANDLE instead PHANDLE. sometimes the timers are fired until 10(or close) cycles.

destroying the timer before all work on timerprocedure(), it can be a problem?

now it's better:


class Timer
{

private:
    static unsigned int TimerCount;
    HANDLE m_timerHandle=NULL;
    UINT_PTR timerid;
    UINT m_uResolution=0;
    unsigned int TimerID=0;
    unsigned int intInterval=0;
    HANDLE gDoneEvent= CreateEvent(NULL, TRUE, FALSE, NULL);

    static void CALLBACK TimerProc(void* InstancePointer, BOOLEAN TimerOrWaitFired)
    {
        Timer* obj=reinterpret_cast<Timer*>(InstancePointer);
        if(obj->timerprocedure)
        {
            obj->timerprocedure();
            SetEvent(obj->gDoneEvent);
        }
    }

public:

    std::function<void()> timerprocedure=EmptyEvent;
    Timer(std::function<void()> tmrprocedure=EmptyEvent)
    {
        TimerCount++;
        TimerID=TimerCount-1;
        timerprocedure=tmrprocedure;
    }

    void Stop()
    {
        WaitForSingleObject(&gDoneEvent,INFINITE);
        DeleteTimerQueueTimer(NULL, m_timerHandle, NULL);
        CloseHandle (m_timerHandle);
        m_timerHandle=NULL;
    }

    unsigned int GetInterval()
    {
        return intInterval;
    }

    void SetInterval(unsigned int uintInterval)
    {
        intInterval = uintInterval;
    }

    property <unsigned int> Interval{GetProperty(Timer::GetInterval),SetProperty(Timer::SetInterval)};

    void Start()
    {
        if(m_timerHandle!=NULL)
            Stop();
        if (CreateTimerQueueTimer(&m_timerHandle,NULL,TimerProc,reinterpret_cast<LPVOID>(this),0,(DWORD)intInterval ,0)==FALSE)
            DebugText("error\t" + to_string(GetLastError()));
    }

    ~Timer()
    {
        if(m_timerHandle!=NULL)
            Stop();
    }
};
unsigned int Timer::TimerCount=0;

i have 2 problems:

1 - but, sometimes i get a memory leak;

2 - and the interval seems more faster...

what you can tell me?

How are you detecting the memory leak? Most tools will point you to the faulting allocation. If not, get better tools ;-)

When you say the interval seems faster... faster than what? What resolution are you expecting/getting?

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

"How are you detecting the memory leak? Most tools will point you to the faulting allocation. If not, get better tools ;-)"

my Windows 7 tell me : 'the program stop responding', after some time(and some cycles).

"When you say the interval seems faster... faster than what? What resolution are you expecting/getting?"

i don't know about the resolution... what i know is the timer been faster... maybe that's why that i'm getting the memory leak

see the actual code:


class Timer
{

private:
    static unsigned int TimerCount;
    HANDLE m_timerHandle=NULL;
    UINT_PTR timerid;
    UINT m_uResolution=0;
    unsigned int TimerID=0;
    unsigned int intInterval=0;
    HANDLE hTimerQueue = CreateTimerQueue();
    HANDLE gDoneEvent= CreateEvent(NULL, TRUE, FALSE, NULL);

    static void CALLBACK TimerProc(PVOID InstancePointer, BOOLEAN TimerOrWaitFired)
    {
        Timer* obj=reinterpret_cast<Timer*>(InstancePointer);
        if(obj->timerprocedure)
        {
            obj->timerprocedure();
            SetEvent(obj->gDoneEvent);
        }
    }

public:

    std::function<void()> timerprocedure=EmptyEvent;
    Timer(std::function<void()> tmrprocedure=EmptyEvent)
    {
        TimerCount++;
        TimerID=TimerCount-1;
        timerprocedure=tmrprocedure;
    }

    void Stop()
    {
        WaitForSingleObject(&gDoneEvent,INFINITE);
        DeleteTimerQueueTimer(hTimerQueue, m_timerHandle, NULL);
        CloseHandle (m_timerHandle);
        m_timerHandle=NULL;
    }

    unsigned int GetInterval()
    {
        return intInterval;
    }

    void SetInterval(unsigned int uintInterval)
    {
        intInterval = uintInterval;
    }

    property <unsigned int> Interval{GetProperty(Timer::GetInterval),SetProperty(Timer::SetInterval)};

    void Start()
    {
        if(m_timerHandle!=NULL)
            Stop();
        if (CreateTimerQueueTimer(&m_timerHandle,hTimerQueue,TimerProc,reinterpret_cast<LPVOID>(this),0,(DWORD)intInterval ,0)==FALSE)
            DebugText("error\t" + to_string(GetLastError()));
    }

    ~Timer()
    {
        if(m_timerHandle!=NULL)
            Stop();
        TimerCount=TimerCount-1;
        if(TimerCount==0)
            DeleteTimerQueue(hTimerQueue);
    }
};
unsigned int Timer::TimerCount=0;

- and maybe you have right.. the problem is the resolution, but i don't know fix that;

- seems that the CreateTimerQueueTimer() can affect the multithread code, right?

That's not a memory leak, that's a crash. Use your debugger.

As for interactions with multithreading, read the documentation - there are many potential pitfalls.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

only these function give me several problems.

and the macro is wrong:


#define WT_SET_MAX_THREADPOOL_THREADS(Flags,Limit) \
    ((Flags)|=(Limit)<<16)

because don't return the result... so i did:


ULONG CreateTimerQueueTimerWT_SET_MAX_THREADPOOL_THREADS(ULONG Flags, ULONG Limit=100)
{
    return ((Flags)|=(Limit)<<16);
}

i know, the name isn't the best, but works...

but continue on problem: i belive, more, that the problem is on CreateTimerQueueTimer(), maybe i'm use it incorrect:


ULONG CreateTimerQueueTimerWT_SET_MAX_THREADPOOL_THREADS(ULONG Flags, ULONG Limit=100)
{
    return ((Flags)|=(Limit)<<16);
}

class Timer
{

private:
    static unsigned int TimerCount;
    HANDLE m_timerHandle=NULL;
    UINT_PTR timerid;
    UINT m_uResolution=0;
    unsigned int TimerID=0;
    unsigned int intInterval=0;
    HANDLE hTimerQueue = CreateTimerQueue();
    HANDLE gDoneEvent= CreateEvent(NULL, TRUE, FALSE, NULL);

    static void CALLBACK TimerProc(PVOID InstancePointer, BOOLEAN TimerOrWaitFired)
    {
        Timer* obj=reinterpret_cast<Timer*>(InstancePointer);
        if(obj->timerprocedure)
        {
            obj->timerprocedure();
            SetEvent(obj->gDoneEvent);
        }
    }

public:

    std::function<void()> timerprocedure=EmptyEvent;
    Timer(std::function<void()> tmrprocedure=EmptyEvent)
    {
        TimerCount++;
        TimerID=TimerCount-1;
        timerprocedure=tmrprocedure;
    }

    void Stop()
    {
        WaitForSingleObject(&gDoneEvent,INFINITE);
        DeleteTimerQueueTimer(hTimerQueue, m_timerHandle, NULL);
        CloseHandle (m_timerHandle);
        m_timerHandle=NULL;
    }

    unsigned int GetInterval()
    {
        return intInterval;
    }

    void SetInterval(unsigned int uintInterval)
    {
        intInterval = uintInterval;
    }

    property <unsigned int> Interval{GetProperty(Timer::GetInterval),SetProperty(Timer::SetInterval)};

    void Start()
    {
        if(m_timerHandle!=NULL)
            Stop();
        if (CreateTimerQueueTimer(&m_timerHandle,hTimerQueue,TimerProc,reinterpret_cast<LPVOID>(this),0,(DWORD)intInterval ,CreateTimerQueueTimerWT_SET_MAX_THREADPOOL_THREADS(0, 200))==FALSE)
            DebugText("error\t" + to_string(GetLastError()));
    }

    ~Timer()
    {
        if(m_timerHandle!=NULL)
            Stop();
        TimerCount=TimerCount-1;
        if(TimerCount==0)
            DeleteTimerQueue(hTimerQueue);
    }
};
unsigned int Timer::TimerCount=0;

readers: like on MSDN: the WaitForSingleObject() is used before destroy the timer... maybe it's the best do it for Multithread and more other Timer functions... is just 1 nice advice.

You're being very unclear about what you are trying versus what you are expecting. I can see your code fine but I have no clue what you want to happen here.

It's very hard to diagnose a problem when the problem is not specified ;-)

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

This topic is closed to new replies.

Advertisement