Ticket #212 (reopened defect)
COM Initialization detection
Reported by: | jasper | Owned by: | jasper |
---|---|---|---|
Priority: | major | Milestone: | Backlog |
Component: | COBIA core | Version: | 1.2.0.14 |
Keywords: | Cc: |
Description
The threading model notes state that COBIA should not initialize COM on a PME thread. Therefore if a COM PMC is instantiated by COBIA, it starts with checking whether COM is initialized on the current PME thread, and if not, it will always create the COM object on a COBIA thread, where COBIA has control over COM initialization and uninitialization.
CoGetApartmentType? is used to do the checking, and in the initial implementation, the pAptType was used and the aptQualifier was ignored.
https://learn.microsoft.com/en-us/windows/win32/api/combaseapi/nf-combaseapi-cogetapartmenttype
If COM MTA is initialized somewhere in the application, on a different thread, and the current thread is not initialized for COM, CoGetApartmentType? returns that the current thread is initialized as MTA, with additional qualifier that this is done implicitly.
APTTYPEQUALIFIER_IMPLICIT_MTA Value: 1 This qualifier is only valid when the pAptType parameter of the CoGetApartmentType function specifies APTTYPE_MTA on return. A thread has an implicit MTA apartment type if it does not initialize the COM apartment itself, and if another thread has already initialized the MTA in the process. This qualifier informs the API caller that the MTA of the thread is implicitly inherited from other threads and is not initialized directly.
It is tempting to allow COM objects to be created on a COBIA PME thread using this machinery.
However, what if the PME proceeds and initializes COM as Apartment thread on the calling thread somewhat later? Or the PMC was not created with the ALLOW_RESTRICTED_THREADING flag and the PME attempt to access it from a thread that is COM initialized as Apartment threaded?
Change History
comment:2 Changed 6 months ago by jasper
- Status changed from closed to reopened
- Resolution fixed deleted
comment:3 Changed 6 months ago by jasper
A temporary fix is in place that considers results of aptQualifier as APTTYPEQUALIFIER_IMPLICIT_MTA or APTTYPEQUALIFIER_NA_ON_IMPLICIT_MTA equal to a non-COM initialized thread.
comment:4 Changed 6 months ago by jasper
Should we try what happens in case
- we have a private thread that initializes COM as MTA (in COBIA)
- this thread sits around until the application exits, and then uninitializes COM
- as a resuls, all PME threads will appear as MTA initialized, with qualifier APTTYPEQUALIFIER_IMPLICIT_MTA
- then we create a COM object in the PME thread (which is now a MTA object)
- then we initialize COM as Apartment threaded from the PME thread
- how does this affect the COM object that was already created?
- how does this affect the CoInitialize? call; will it succeed?
if CoInitialize? succeeds to initialize the current thread as ApartmentThread? and the already created COM object continues to function as MTA COM object, then we should probably allow this machinery, and in fact force it by the above mentioned thread, to prevent COM objects from always being marshaled in COBIA PME in the absence of explicit COM initialization.
In [939fb737c53d70e9c86d087c9144013da0ba0f45]: