Implementing an Event Provider

[This is preliminary documentation and subject to change.]

An event provider is implemented as a COM object that exposes a class identifier (CLSID) and supports one required interface: IWbemEventProvider. IWbemEventProvider has one method that it adds to the three IUnknown methods: ProvideForNamespace.

CIMOM calls an event provider's ProvideForNamespace method soon after it loads the provider. In the call, CIMOM passes a pointer to the sink, the target location for the event. Event providers must increment the reference count on the sink by calling its IWbemObjectSink::AddRef method, the standard COM method for incrementing a reference count. There are no special requirements that CIMOM introduces above and beyond the COM standard.

CIMOM also supplies an IWbemServices pointer to an event provider in the ProvideForNamespace call. Event providers can use this pointer to request services such as the creation or deletion of instances. Event providers should increment the reference count on the services object using the standard COM technique by calling IWbemServices::AddRef and return immediately. A separate thread must be spawned for sending events.

To access and load an event provider, CIMOM creates a separate provider object using the COM function CoCreateInstance. This call is made for each namespace that CIMOM requires the event provider to function in. When CIMOM no longer requires the provider, it calls IWbemEventProvider::Release.

A second interface, IWbemEventProviderQuerySink, can also be implemented by an event provider as an option. IWbemEventProviderQuerySink is most useful for providers that generate multiple types of notifications because it allows them to produce notifications based on specific consumer requests. IWbemEventProviderQuerySink helps to avoid sending useless event notifications.

IWbemEventProviderQuerySink includes two methods in addition to those inherited from IUnknown: NewQuery and CancelQuery. Whenever CIMOM receives a new or modified query on behalf of a consumer, CIMOM calls the NewQuery method to echo the query to the provider. The provider can examine the query to see what event notifications are actually being requested. For example, a provider supporting ten classes of events does not want to generate notifications for all classes unless absolutely necessary. IWbemEventProviderQuerySink allows a provider to examine incoming queries and generate only notifications that will be delivered to a registered consumer. Whenever a consumer registration is cancelled, CIMOM calls CancelQuery to report the cancellation to the provider.

For more information about creating and evaluating queries, see WBEM Query Language.

Whereas IWbemEventProvider is called only once after an event provider becomes active, IWbemEventProviderQuerySink is called continuously as appropriate. The provider can ignore all calls at its own discretion. This is very important; supporting IWbemEventProviderQuerySink indicates that a provider has agreed to supply at least the events that are requested by the queries. A provider can generate more events than are requested and CIMOM will post-filter the events as appropriate. This gives providers the freedom to implement IWbemEventProviderQuerySink and optimize their processing without a complete understanding of the query language. For instance, if a provider cannot understand a particular query, it can generate all possible events.

Whereas IWbemEventProvider is called only once after an event provider becomes active, IWbemEventProviderQuerySink is called continuously as appropriate. The provider can ignore all calls at its own discretion.

Because not all event providers support IWbemEventProviderQuerySink, CIMOM calls a provider's IWbemEventProvider::QueryInterface method at load time to determine if support exists.

Event providers that want to supply many notifications rapidly for the same class of event should reuse the same event object. CIMOM never holds onto the event object past the completion of the IWbemObjectSink::Indicate call.