windows-nt/Source/XPSP1/NT/enduser/netmeeting/t120/mst123/timer.cpp
2020-09-26 16:20:57 +08:00

294 lines
9.2 KiB
C++
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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;
}
}
}