Help on Waitable Timer functions

Just starting out? Need help? Post your questions and find answers here.
aXend
Enthusiast
Enthusiast
Posts: 103
Joined: Tue Oct 07, 2003 1:21 pm
Location: Netherlands

Help on Waitable Timer functions

Post by aXend »

I want to use the Win32 Waitable Timer functions to set a timer and do something. The problem is that the returncodes of the functions are OK, but nothing happens. What am I doing wrong?

Code: Select all

Procedure DateToFileTime(datum,*ft.FILETIME) 
  st.systemtime 
  st\wYear=Year(datum):st\wMonth=Month(datum):st\wDay=Day(datum)
  st\wHour=Hour(datum):st\wMinute=Minute(datum):st\wSecond=Second(datum):st\wMilliseconds=0 
  SystemTimeToFileTime_(st,*ft) 
EndProcedure 

Procedure TimerProc(a.l,b.l,c.l)
  MessageRequester("Timer","Now started",0)
EndProcedure

hTimer.l = CreateWaitableTimer_(0,#False,"MyTimer")
If hTimer
  ft.FILETIME
  datum=Date(2004,10,12,13,07,00) ; set date and time for timer (within 2 minutes)
  DateToFileTime(datum,ft) 

  success.l = SetWaitableTimer_(hTimer,ft,0,@TimerProc(),0,#False)
  If success = 0
    MessageRequester("Timer", GetErrorDescription(),0)
  Else
    Debug success
    WaitForSingleObject_(hTimer,120000) ; time-out after 2 minutes (= 120.000 millisecconds)
  EndIf

  CloseHandle_(hTimer)
EndIf

End
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Post by wilbert »

Your DateToFileTime function isn't correct. You need to convert your local time to UTC. Here's the corrected function

Code: Select all

Procedure DateToFileTime(datum,*ft.FILETIME)
  st.systemtime
  st\wYear=Year(datum):st\wMonth=Month(datum):st\wDay=Day(datum)
  st\wHour=Hour(datum):st\wMinute=Minute(datum):st\wSecond=Second(datum):st\wMilliseconds=0
  SystemTimeToFileTime_(st,*ft)
  LocalFileTimeToFileTime_(*ft, *ft)
EndProcedure
aXend
Enthusiast
Enthusiast
Posts: 103
Joined: Tue Oct 07, 2003 1:21 pm
Location: Netherlands

Post by aXend »

Wilbert, thanks for the correction. I have changed the code, but it still doesn't work. Did it work for you?
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Post by wilbert »

Yes, it worked for me. Of course you have to add something to see that it works. For example add Debug "END" just before your end command to check that it actually came out of the waitable timer.

Edit:
If you want to make sure it's the filetime that's causing the problem, try a relative timer. Set ft using the lines below to wait for 20 seconds

ft\dwHighDateTime = -1
ft\dwLowDateTime = -10000000 * 20
Last edited by wilbert on Tue Oct 12, 2004 2:56 pm, edited 1 time in total.
aXend
Enthusiast
Enthusiast
Posts: 103
Joined: Tue Oct 07, 2003 1:21 pm
Location: Netherlands

Post by aXend »

I did add something. The SetWaitableTimer_() function points to the TimerProc() to be called when the timer goes off. But with me it never does anything. It looks as if that didn't happen with you either. Any other suggestions?
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Post by wilbert »

I overlooked you timer proc :wink:
Here's the working code

Code: Select all

Procedure DateToFileTime(datum,*ft.FILETIME)
  st.systemtime
  st\wYear=Year(datum):st\wMonth=Month(datum):st\wDay=Day(datum)
  st\wHour=Hour(datum):st\wMinute=Minute(datum):st\wSecond=Second(datum):st\wMilliseconds=0
  SystemTimeToFileTime_(st,*ft)
  LocalFileTimeToFileTime_(*ft, *ft)
EndProcedure

Procedure TimerProc(a.l,b.l,c.l)
  MessageRequester("Timer","Now started",0)
EndProcedure

hTimer.l = CreateWaitableTimer_(0,#False,"MyTimer")
If hTimer
  ft.FILETIME
  datum=Date(2004,10,12,16,25,00) ; set date and time for timer (within 2 minutes)
  DateToFileTime(datum,ft)

  success.l = SetWaitableTimer_(hTimer,ft,0,@TimerProc(),0, #False)
  If success = 0
    MessageRequester("Timer", GetErrorDescription(),0)
  Else
    Debug success
    SleepEx_(#Infinite, #True )
  EndIf
  CloseHandle_(hTimer)
EndIf

End 
and the explanation why your code didn't work (besides the local time issue) ...
When you are using a waitable timer with an APC, the thread that sets the timer should not wait on the handle of the timer. By doing so, you would cause the thread to wake up as a result of the timer becoming signaled rather than as the result of an entry being added to the APC queue.
aXend
Enthusiast
Enthusiast
Posts: 103
Joined: Tue Oct 07, 2003 1:21 pm
Location: Netherlands

Post by aXend »

Thanks again, now it works! :D
Strange though, I tried SleepEx_() too, but that resulted in hanging the system. I'm not sure if I understand the explanation completely. :oops: I'm new to this kind of processing. I'll continue my exploration....
Post Reply