Partager via


Provider Threading Responsibilities

Free-threaded in-process OLE DB objects have the following threading responsibilities:

  • To implement the guarding mechanisms necessary to guarantee safe operation of the OLE DB objects when objects are called from different threads. The choice of these mechanisms is provider-specific.

  • To guarantee an operation free of deadlocks and of starvation.

  • In the case of rowset objects, to shield other threads executing concurrently from the effects of methods like IRowsetUpdate::Update or IRowsetRefresh::RefreshVisibleData that may change the state of the rowset's copies of the rows. Update should be an atomic operation. While working in immediate update mode, all methods that modify the rowset's copies of the rows (IRowsetChange::SetData, IRowsetChange::DeleteRows, and so on) should also be atomic operations.

  • In the case of rowset objects, to guarantee that all other provider-implemented objects for which the rowset is a factory (such as other rowsets or storage objects) are also free-threaded.

  • To guarantee a minimum of marshaling support for their use by apartment-model consumers; for example, by aggregating to them an IMarshal object obtained from CoCreateFreeThreadedMarshaler. The provider can perform this aggregation lazily ? that is, defer it until QueryInterface requests IMarshal.

Apartment model in-process OLE DB objects have the following threading responsibilities:

  • The provider must assume that the OLE DB object will always receive direct calls on the same thread (apartment) on which it was created. Objects, however, can be created on different threads. Apartment objects belong to the same thread for all their existence.

  • Apartment objects must use a proxy-stub mechanism to accept calls from other apartments. For this, CoMarshalInterface accepts a flag (MSHCTX_INPROC) to describe an interapartment communication. In the apartment model, calls using these proxy-stubs are synchronized in the same manner as Windows messages synchronize calls.

    Apartment model in-process OLE DB objects

example of processing in two apartments

  • In the case of rowset objects, the provider should guarantee that all other objects created by the rowset and returned by it, such as other rowsets or storage objects, are also apartment model and belong to the same thread as their ancestor rowset.

  • Apartment OLE DB objects should not share state with other OLE DB objects because these objects may reside in different threads. The exception to this rule is OLE DB objects that have an ancestor/descendant relationship, such as those created by IColumnsRowset::GetColumnsRowset. Because these objects belong to the same apartment, they are guaranteed to execute serially and may share state safely, if needed.

  • The provider should furnish marshaling support (proxy/stub) for all the object's interfaces.