You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
294 lines
9.5 KiB
294 lines
9.5 KiB
#include "precomp.h"
|
|
DEBUG_FILEZONE(ZONE_T120_T123PSTN);
|
|
|
|
/* Timer.cpp
|
|
*
|
|
* Copyright (c) 1993-1995 by DataBeam Corporation, Lexington, KY
|
|
*
|
|
* Abstract:
|
|
* This is the implementation file for the Timer class
|
|
*
|
|
* Private Instance Variables:
|
|
* Maximum_Timer_Events - Maximum number of timers maintained
|
|
* by this class
|
|
* Timer_Memory - Base address of our TimerEvent
|
|
* structure memory
|
|
* Timer_Event_Table - Address of first structure in
|
|
* Timer_Memory
|
|
* Timer_Event_Count - Number of timers active
|
|
* Timer_Event_Free_Stack - Holds numbers of available timers
|
|
* First_Timer_Event_In_Chain - Number of first timer in the chain
|
|
* Last_Timer_Value - Last time that we got from Windows
|
|
* Timer_Info - Windows structure that holds the
|
|
* current time.
|
|
*
|
|
* Caveats:
|
|
* None
|
|
*
|
|
* Author:
|
|
* James P. Galvin
|
|
* James W. Lawwill
|
|
*/
|
|
#include <windowsx.h>
|
|
#include "timer.h"
|
|
|
|
|
|
/*
|
|
* Timer (void)
|
|
*
|
|
* Public
|
|
*
|
|
* Functional Description:
|
|
* This is the constructor for the timer class. This procedure gets
|
|
* thc current Windows system time.
|
|
*/
|
|
Timer::Timer (void) :
|
|
Timer_List (TRANSPORT_HASHING_BUCKETS),
|
|
Timer_Event_Free_Stack ()
|
|
{
|
|
/*
|
|
** Get the current time from Windows
|
|
*/
|
|
Last_Timer_Value = GetTickCount ();
|
|
Maximum_Timer_Events = 0;
|
|
Timer_Event_Count = 0;
|
|
First_Timer_Event_In_Chain=NULL;
|
|
}
|
|
|
|
|
|
/*
|
|
* ~Timer (void)
|
|
*
|
|
* Public
|
|
*
|
|
* Functional Description:
|
|
* This is the destructor for the timer class. This routine frees all
|
|
* memory associated with timer events.
|
|
*/
|
|
Timer::~Timer (void)
|
|
{
|
|
PTimerEvent lpTimerEv;
|
|
|
|
Timer_List.reset();
|
|
while (Timer_List.iterate ((PDWORD_PTR) &lpTimerEv))
|
|
delete lpTimerEv;
|
|
}
|
|
|
|
|
|
/*
|
|
* TimerEventHandle Timer::CreateTimerEvent (
|
|
* ULONG timer_duration,
|
|
* USHORT control_flags,
|
|
* IObject * object_ptr,
|
|
* PTimerFunction timer_func_ptr)
|
|
*
|
|
* Public
|
|
*
|
|
* Functional Description:
|
|
* This routine is called to create a timer event. The routine stores the
|
|
* information passed-in in a TimerEvent structure. When the timer expires
|
|
* the function will be called.
|
|
*
|
|
*/
|
|
TimerEventHandle Timer::CreateTimerEvent
|
|
(
|
|
ULONG timer_duration,
|
|
USHORT control_flags,
|
|
IObject *object_ptr,
|
|
PTimerFunction timer_func_ptr
|
|
)
|
|
{
|
|
TimerEventHandle timer_event=NULL;
|
|
PTimerEvent next_timer_event;
|
|
PTimerEvent timer_event_ptr;
|
|
|
|
/*
|
|
** Get the current time from Windows
|
|
*/
|
|
Last_Timer_Value = GetTickCount ();
|
|
|
|
if (Maximum_Timer_Events > Timer_Event_Count)
|
|
{
|
|
/*
|
|
** Get the next available handle from the free stack
|
|
*/
|
|
timer_event = (TimerEventHandle) Timer_Event_Free_Stack.get();
|
|
Timer_Event_Count++;
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
** Assign the timer event counter to the handle
|
|
*/
|
|
timer_event = ++Timer_Event_Count;
|
|
Maximum_Timer_Events++;
|
|
}
|
|
/*
|
|
** If this is the first event to be created, keep track of it
|
|
** so when we iterate through the list, we will know where to
|
|
** start.
|
|
*/
|
|
timer_event_ptr = new TimerEvent;
|
|
if (First_Timer_Event_In_Chain == NULL)
|
|
{
|
|
First_Timer_Event_In_Chain = timer_event_ptr;
|
|
next_timer_event = NULL;
|
|
}
|
|
else
|
|
{
|
|
next_timer_event = First_Timer_Event_In_Chain;
|
|
First_Timer_Event_In_Chain -> previous_timer_event =
|
|
timer_event_ptr;
|
|
|
|
}
|
|
First_Timer_Event_In_Chain = timer_event_ptr;
|
|
Timer_List.insert ((DWORD_PTR) timer_event, (DWORD_PTR) timer_event_ptr);
|
|
/*
|
|
** Fill in the TimerEvent structure
|
|
*/
|
|
timer_event_ptr->event_handle=timer_event;
|
|
timer_event_ptr->timer_duration = timer_duration;
|
|
timer_event_ptr->total_duration = timer_duration;
|
|
timer_event_ptr->object_ptr = object_ptr;
|
|
timer_event_ptr->timer_func_ptr = timer_func_ptr;
|
|
timer_event_ptr->control_flags = control_flags | TIMER_EVENT_IN_USE;
|
|
timer_event_ptr->next_timer_event = next_timer_event;
|
|
timer_event_ptr->previous_timer_event = NULL;
|
|
|
|
return (timer_event);
|
|
}
|
|
|
|
|
|
/*
|
|
* TimerError Timer::DeleteTimerEvent (TimerEventHandle timer_event)
|
|
*
|
|
* Public
|
|
*
|
|
* Functional Description:
|
|
* This routine is called by the user to delete a timer event that is
|
|
* currently active.
|
|
*/
|
|
TimerError Timer::DeleteTimerEvent (TimerEventHandle timer_event)
|
|
{
|
|
TimerError return_value;
|
|
PTimerEvent timer_event_ptr;
|
|
PTimerEvent previous_timer_event_ptr;
|
|
PTimerEvent next_timer_event_ptr;
|
|
|
|
if (Timer_List.find ((DWORD_PTR) timer_event, (PDWORD_PTR) &timer_event_ptr) == FALSE)
|
|
return_value = TIMER_INVALID_TIMER_HANDLE;
|
|
else
|
|
{
|
|
Timer_List.remove ((DWORD) timer_event);
|
|
if (!(timer_event_ptr->control_flags & TIMER_EVENT_IN_USE))
|
|
return_value = TIMER_INVALID_TIMER_HANDLE;
|
|
else
|
|
{
|
|
if (timer_event_ptr->previous_timer_event == NULL)
|
|
First_Timer_Event_In_Chain =
|
|
timer_event_ptr->next_timer_event;
|
|
else
|
|
{
|
|
previous_timer_event_ptr =
|
|
timer_event_ptr->previous_timer_event;
|
|
previous_timer_event_ptr->next_timer_event =
|
|
timer_event_ptr->next_timer_event;
|
|
}
|
|
if (timer_event_ptr->next_timer_event != NULL)
|
|
{
|
|
next_timer_event_ptr =
|
|
timer_event_ptr->next_timer_event;
|
|
next_timer_event_ptr->previous_timer_event =
|
|
timer_event_ptr->previous_timer_event;
|
|
}
|
|
delete timer_event_ptr;
|
|
Timer_Event_Free_Stack.append ((DWORD) timer_event);
|
|
--Timer_Event_Count;
|
|
|
|
return_value = TIMER_NO_ERROR;
|
|
}
|
|
}
|
|
return (return_value);
|
|
}
|
|
|
|
|
|
/*
|
|
* void Timer::ProcessTimerEvents (void)
|
|
*
|
|
* Public
|
|
*
|
|
* Functional Description:
|
|
* This routine MUST be called frequently and regularly so that we can
|
|
* manage our timers. This function gets the current system time and
|
|
* goes through each of the timers to see which have expired. If a timer
|
|
* has expired, we call the function associated with it. Upon return,
|
|
* if the timer was marked as a one-shot event, we remove it from our
|
|
* list of timers.
|
|
*/
|
|
void Timer::ProcessTimerEvents (void)
|
|
{
|
|
TimerEventHandle timer_event;
|
|
TimerEventHandle next_timer_event;
|
|
PTimerEvent timer_event_ptr;
|
|
IObject * object_ptr;
|
|
PTimerFunction timer_func_ptr;
|
|
ULONG timer_increment;
|
|
DWORD timer_value;
|
|
|
|
|
|
if (!First_Timer_Event_In_Chain)
|
|
return;
|
|
|
|
/*
|
|
** Get the current time
|
|
*/
|
|
timer_value = GetTickCount ();
|
|
timer_increment = timer_value - Last_Timer_Value;
|
|
Last_Timer_Value = timer_value;
|
|
|
|
next_timer_event = First_Timer_Event_In_Chain->event_handle;
|
|
|
|
/*
|
|
** Go through each of the timer events to see if they have expired
|
|
*/
|
|
while (Timer_List.find ((DWORD_PTR) next_timer_event, (PDWORD_PTR) &timer_event_ptr))
|
|
{
|
|
timer_event = timer_event_ptr->event_handle;
|
|
/*
|
|
** Has the timer expired?
|
|
*/
|
|
if (timer_event_ptr->timer_duration <= timer_increment)
|
|
{
|
|
object_ptr = timer_event_ptr->object_ptr;
|
|
timer_func_ptr = timer_event_ptr->timer_func_ptr;
|
|
|
|
/*
|
|
** Call the function before deleting...
|
|
** otherwise the function could manipulate the list
|
|
** and we wouldn't know if the one we're pointing to
|
|
** is still valid
|
|
*/
|
|
(object_ptr->*timer_func_ptr) (timer_event);
|
|
// Get the next timer_event_handle
|
|
if (timer_event_ptr->next_timer_event)
|
|
next_timer_event = timer_event_ptr->next_timer_event->event_handle;
|
|
else
|
|
next_timer_event = NULL;
|
|
if (timer_event_ptr->control_flags & TIMER_EVENT_ONE_SHOT)
|
|
DeleteTimerEvent (timer_event);
|
|
else
|
|
timer_event_ptr->timer_duration =
|
|
timer_event_ptr->total_duration;
|
|
}
|
|
else
|
|
{
|
|
// Get the next timer_event_handle
|
|
if (timer_event_ptr->next_timer_event)
|
|
next_timer_event = timer_event_ptr->next_timer_event->event_handle;
|
|
else
|
|
next_timer_event = NULL;
|
|
timer_event_ptr->timer_duration -= timer_increment;
|
|
}
|
|
}
|
|
}
|
|
|