Ticket #198 (closed defect: fixed)

Opened 4 weeks ago

Last modified 4 weeks ago

COM object creation should adhere to threading model

Reported by: jasper Owned by: jasper
Priority: major Milestone: Phase III WP1
Component: COBIA core Version: 1.2.0.14
Keywords: Cc:

Description

COM objects that are crated from COBIA should be created in accordance with threading model memo

Attachments

Guidelines-For-Threading_CP.pdf (610.6 KB) - added by jasper 4 weeks ago.
Threading memo (draft)

Change History

comment:1 Changed 4 weeks ago by jasper

As described in WAF-10

Changed 4 weeks ago by jasper

Threading memo (draft)

comment:2 Changed 4 weeks ago by jasper

I would like to point out that in the scenario in which a COBIA PME does not initialize COM on the current thread, and asks for creation of an out-of-process COM object (e.g. a LocalServer?), it will be double-marshaled:

  • because we may not initialize COM on the current thread, COBIA will have to create the object in a COBIA marshaling thread, which is the first marshaling that occurs
  • COM will subsequently marshal a second time because the object itself is out of process.

I do not see a work around for this situation - let's hope nobody creates out-of-process COM servers.

Implementation details:

  • Single threaded thread pool threads always initialize COM as apartment threaded on Windows
  • Multi-threaded pool threads always initialize COM as multi-threaded on Windows
  • COINIT_SPEED_OVER_MEMORY is specified at COM initialization
  • if COM initialization fails, this is not flagged - as the thread may want to create non-COM objects in any case. However, in this scenario CoCreateInstance? will fail, as there is nothing else on the thread that initializes COM. We will have very few diagnostics at this point why CoCreateInstance? fails other than that it will say that COM is not initialized.
  • if COM initialization succeeds, it is cleaned up when the thread pool thread exists
  • as the PME initializes COM, or COM is initialized by the marshaler threads, the COM initialization has been removed from COMBIA

There are no structural tests in place. I ran COM objects in the ThermoClientPME to check that all goes well. Then I added COM initialization to the ThermoClientPME and checked that all goes well. So one-off testing has been done. The ThermoClientPME example got the following code:

#ifdef _WIN32

//On Windows we initialize COM to prevent that COBIA is forced to create
// COM objects in a marshaling thread (on which COBIA is free to initialize
// COM itself - it cannot do so on a PME thread).
//This particular application is a single threaded application and only
// uses COM objects in the main thread; additionally it specifies
// CapePMCCreationFlag_AllowRestrictedThreading on all PMC creation.
//We initialize COM as Apartmnent threaded accordingly so that COM
// objects with threading models "Apartment" and "Both" can be created
// without marshaling.
class COMInitializer {
public:
    COMInitializer() {
        CoInitializeEx(NULL,COINIT_APARTMENTTHREADED);
    }
    ~COMInitializer() {
        CoUninitialize();
    }
};

#else

//does nothing if not on Windows
class COMInitializer {
};

#endif

An instance of COMInitializer is created in the main thread. It is verified that no marshaling occures for Apartment threaded COM objects in this scenario.

comment:3 Changed 4 weeks ago by jasper

  • Status changed from new to closed
  • Resolution set to fixed
Note: See TracTickets for help on using tickets.