This base class implements the IReferenceClock interface.
The CBaseReferenceClock class provides a full implementation of IReferenceClock. It uses CCritSec locking support and CAMSchedule scheduler support.
Each advise call defines a point in time when the caller wants to be notified. A periodic advise is a regular series of such events. A list of these advise requests is maintained by the reference clock. The clock calculates the delay until the first requested advise, and signals an event at the due time.
Clients are not advised through callbacks. One-shot clients have an event set, while periodic clients have a semaphore released for each event notification. A semaphore allows a client to know exactly how many events were actually triggered, because multiple time periods might elapse before the client code executes.
During class construction, a worker thread is created. This thread executes a series of Microsoft® Win32® WaitForSingleObject calls, waking up when a command is given to the thread or the next wake-up point is reached. The wake-up points are determined by clients making advise calls.
Protected Data Members
m_pSchedule | Pointer to the CAMSchedule object associated with this CBaseReferenceClock object. |
Member Functions
Name | Description |
CBaseReferenceClock | Constructs a CBaseReferenceClock object. |
GetSchedule | Returns the CAMSchedule pointer stored in the CBaseReferenceClock::m_pSchedule data member. |
SetTimeDelta | Adjusts the values returned from CBaseReferenceClock::GetPrivateTime by the amount specified in this member function. |
TriggerThread | Triggers the advise thread's event. If you override CBaseReferenceClock::GetPrivateTime, you should either reuse or abandon this method. |
Implemented IReferenceClock Methods
Name | Description |
AdvisePeriodic | Requests an asynchronous periodic notification that a time has elapsed. |
AdviseTime | Requests an asynchronous notification that a time has elapsed. |
GetTime | Returns a reference time. |
Unadvise | Removes a previously established advise link. |
Overridable Member Functions
Name | Description |
GetPrivateTime | Gets the current time from the real clock. Override this member function to implement your own clock. |
Implemented INonDelegatingUnknown Methods
Name | Description |
NonDelegatingQueryInterface | Returns a pointer to interfaces supported, that is, IReferenceClock. |
Sets up a recurring advise with the reference clock.
HRESULT AdvisePeriodic(
REFERENCE_TIME StartTime,
REFERENCE_TIME PeriodTime,
HSEMAPHORE hSemaphore,
DWORD *pdwAdviseToken
);
Returns one of the following HRESULT values:
Value | Meaning |
E_OUTOFMEMORY | Failure. |
E_INVALIDARG | Invalid argument. |
NOERROR | No error. |
This member function implements the IReferenceClock::AdvisePeriodic method. A semaphore is used, rather than an event, to ensure that multiple notifications can be seen by the user. Each time an amount of time specified in the PeriodTime parameter elapses, the semaphore will be released.
When no further notifications are required, call CBaseReferenceClock::Unadvise and pass the pdwAdviseToken value returned from this call.
For example, the following code extract sets up an advise link that fires its first advise five seconds from now and then signals every second until Unadvise is called. By using a semaphore with a count of 10, the clock is effectively able to cache 10 events.
HANDLE hSemaphore = CreateSemaphore(NULL, 0, 10, NULL); // assume pRefClock is an IReferenceClock* variable REFERENCE_TIME rtPeriodTime = 1000 * (UNITS / MILLISECONDS); // a one-second interval REFERENCE_TIME rtNow; DWORD dwAdviseToken; pRefClock->GetTime(&rtNow); pRefClock->AdvisePeriodic(rtNow+(5*rtPeriodTime), PeriodTime, hSemaphore, &dwAdviseToken);
Sets up a one-shot notification with the clock.
HRESULT AdviseTime(
REFERENCE_TIME baseTime,
REFERENCE_TIME streamTime,
HEVENT hEvent,
DWORD *pdwAdviseToken
);
Returns one of the following HRESULT values:
Value | Meaning |
E_OUTOFMEMORY | Failure. |
E_INVALIDARG | Invalid argument. |
NOERROR | No error. |
This member function implements the IReferenceClock::AdviseTime method. At the time specified in the baseTime plus the streamTime parameters, the event specified in hEvent will be set. It is correct to call CBaseReferenceClock::Unadvise to remove the link after the event has occurred, but it is not necessary. One-shot notifications are automatically cleared by the clock once they have signaled.
To cancel a one-shot notification before the time is reached, call Unadvise and pass the pdwAdviseToken value returned from this call.
Constructs a CBaseReferenceClock object.
CBaseReferenceClock(
TCHAR *pName,
LPUNKNOWN pUnk,
HRESULT *phr,
CAMSchedule * pSched
);
No return value.
Retrieves the current reference time.
virtual REFERENCE_TIME GetPrivateTime( );
Returns the current reference time, in 100-nanosecond units.
GetPrivateTime represents the actual clock. GetTime is the externally used member function. Derived classes will probably override this method, but not GetTime itself. The important point about GetPrivateTime is that it is allowed to go backward. This class's GetTime member function will keep returning the last time returned by GetTime until GetPrivateTime catches up.
Retrieves the CAMSchedule pointer stored in the CBaseReferenceClock::m_pSchedule data member.
CAMSchedule * GetSchedule( );
Retrieves the current reference time, in 100-nanosecond units.
HRESULT GetTime(
REFERENCE_TIME *pTime
);
Returns one of the following HRESULT values:
Value | Meaning |
E_POINTER | NULL pointer argument. |
S_FALSE | Failure. |
S_OK | Success. |
This member function implements the IReferenceClock::GetTime method. It reads the time from the implemented clock and returns the current time.
Accesses supported interfaces.
HRESULT NonDelegatingQueryInterface(
REFIID riid,
void ** ppv
);
Returns S_OK if the interface is supported, S_FALSE if not.
This member function implements the INonDelegatingUnknown::NonDelegatingQueryInterface method.
Sets a delta on the time that CBaseReferenceClock::GetPrivateTime will return.
HRESULT SetTimeDelta(
const REFERENCE_TIME& TimeDelta
);
Returns NOERROR.
Note that CBaseReferenceClock::GetTime will never return a time earlier than a previously returned time. Thus, if you set the clock to a time in the past, successive calls to CBaseReferenceClock::GetTime will return the current value until this new time is reached, and the clock will start to increment again.
Triggers the advise thread's event.
void TriggerThread( );
No return value.
The clock uses a worker thread that should wake up and call CAMSchedule::Advise at the appropriate time. If the clock adds an event that should be fired earlier than any currently outstanding event, the worker thread needs to be awoken in order to reevaluate its wait time. The TriggerThread member function will wake up the worker thread so this can take place. If a derived clock causes time to jump forward for some reason, TriggerThread should be called so that the wait time can be reevaluated; otherwise, the events will fire late.
Removes a previously established advise link.
HRESULT Unadvise(
DWORD dwAdviseToken
);
Returns S_OK if the successful, S_FALSE if not.
This member function implements the IReferenceClock::Unadvise method. Call Unadvise to remove the previously established clock advise links. It is mandatory to call Unadvise on periodic advises in order to stop further calls. It is recommended to call Unadvise for single-shot advise links.
© 1997 Microsoft Corporation. All rights reserved. Terms of Use.