## CBaseReferenceClock Class

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.

###

CBaseReferenceClock::AdvisePeriodic

CBaseReferenceClock Class

Sets up a recurring advise with the reference clock.

HRESULT AdvisePeriodic(
REFERENCE_TIME StartTime,
REFERENCE_TIME PeriodTime,
HSEMAPHORE hSemaphore,
DWORD *pdwAdviseToken
);

##### Parameters

StartTime
  Start at this time.
PeriodTime
  Time between notifications.
hSemaphore
  Advise through a semaphore.
pdwAdviseToken
  Advise token that identifies the link with the clock.

##### Return Values

Returns one of the following HRESULT values:

Value | Meaning
E_OUTOFMEMORY | Failure.
E_INVALIDARG | Invalid argument.
NOERROR | No error.

##### Remarks

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);

###

CBaseReferenceClock::AdviseTime

CBaseReferenceClock Class

Sets up a one-shot notification with the clock.

HRESULT AdviseTime(
REFERENCE_TIME baseTime,
REFERENCE_TIME streamTime,
HEVENT hEvent,
DWORD *pdwAdviseToken
);

##### Parameters

baseTime
  Base reference time.
streamTime
  Stream offset time.
hEvent
  Advise through this event.
pdwAdviseToken
  Where the advise token goes.

##### Return Values

Returns one of the following HRESULT values:

Value | Meaning
E_OUTOFMEMORY | Failure.
E_INVALIDARG | Invalid argument.
NOERROR | No error.

##### Remarks

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.

###

CBaseReferenceClock::CBaseReferenceClock

CBaseReferenceClock Class

Constructs a CBaseReferenceClock object.

CBaseReferenceClock(
TCHAR *pName,
LPUNKNOWN pUnk,
HRESULT *phr,
CAMSchedule * pSched
);

##### Parameters

pName
  Name of the CBaseReferenceClock object.
pUnk
  IUnknown interface of the delegating object.
phr
  Address of an HRESULT value.
pSched
  Address of a CAMSchedule object that will be associated with this CBaseReferenceClock object. If pSched is NULL, the constructor creates a new CAMSchedule object and associates it with this CBaseReferenceClock object.

##### Return Values

No return value.

###

CBaseReferenceClock::GetPrivateTime

CBaseReferenceClock Class

Retrieves the current reference time.

virtual REFERENCE_TIME GetPrivateTime( );

##### Return Values

Returns the current reference time, in 100-nanosecond units.

##### Remarks

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.

###

CBaseReferenceClock::GetSchedule

CBaseReferenceClock Class

Retrieves the CAMSchedule pointer stored in the CBaseReferenceClock::m_pSchedule data member.

CAMSchedule * GetSchedule( );

###

CBaseReferenceClock::GetTime

CBaseReferenceClock Class

Retrieves the current reference time, in 100-nanosecond units.

HRESULT GetTime(
REFERENCE_TIME *pTime
);

##### Parameters

pTime
  Where the current time is returned.

##### Return Values

Returns one of the following HRESULT values:

Value | Meaning
E_POINTER | NULL pointer argument.
S_FALSE | Failure.
S_OK | Success.

##### Remarks

This member function implements the IReferenceClock::GetTime method. It reads the time from the implemented clock and returns the current time.

###

CBaseReferenceClock::NonDelegatingQueryInterface

CBaseReferenceClock Class

Accesses supported interfaces.

HRESULT NonDelegatingQueryInterface(
REFIID riid,
void ** ppv
);

##### Parameters

riid
  IID of the interface being requested. Only IID_IReferenceClock is supported by the clock interface.
ppv
  Where the IReferenceClock pointer is returned.

##### Return Values

Returns E_POINTER if ppv is invalid. Returns NOERROR if the query is successful or E_NOINTERFACE if it is not.

##### Remarks

This member function implements the INonDelegatingUnknown::NonDelegatingQueryInterface method.

###

CBaseReferenceClock::SetTimeDelta

CBaseReferenceClock Class

Sets a delta on the time that CBaseReferenceClock::GetPrivateTime will return.

HRESULT SetTimeDelta(
const REFERENCE_TIME& TimeDelta
);

##### Parameters

TimeDelta
  REFERENCE_TIME delta to be added.

##### Return Values

Returns NOERROR.

##### Remarks

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.

###

CBaseReferenceClock::TriggerThread

CBaseReferenceClock Class

Triggers the advise thread's event.

void TriggerThread( );

##### Return Values

No return value.

##### Remarks

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.

###

CBaseReferenceClock::Unadvise

CBaseReferenceClock Class

Removes a previously established advise link.

HRESULT Unadvise(
DWORD dwAdviseToken
);

##### Parameters

dwAdviseToken
  Identifier (token) of the link that is being reset. This is the same value that was returned on CBaseReferenceClock::AdviseTime or CBaseReferenceClock::AdvisePeriodic.

##### Return Values

Returns S_OK if the successful, S_FALSE if not.

##### Remarks

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.