About CoInitializeEx

Mike Kaganski mikekaganski at hotmail.com
Fri May 29 15:19:39 UTC 2020

On 29.05.2020 17:41, julien2412 wrote:
> warn:extensions.olebridge:3356:12452:extensions/source/ole/olethread.cxx:41:
> CoInitializeEx failed (expectedly): Cannot change thread mode after it is
> set.
> warn:extensions.olebridge:3356:12452:extensions/source/ole/olethread.cxx:61:  
> Thread is in a main single-threaded apartment.
> ...
> So now, I check if there's a call to CoUnInitialize for each CoInitializeEx
> and I noticed this:
> 58  ODriver::~ODriver()
> 59  {
> 60      CoUninitialize();
> 61      CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
> 62  }
> See
> https://opengrok.libreoffice.org/xref/core/connectivity/source/drivers/ado/ADriver.cxx?r=b587de60#49
> I thought about removing line 61 (the reinit with CoInitializeEx) in dtr.
> Indeed if a component needs to initialize COM library, I suppose it should
> be its responsability.
> However, I wonder if a thread which would have already initialized COM
> library could call ADO part and so would expect that when ADO finished its
> job, to have COM still initialized.
> But even in this case, it could be wrong since ADO dtr always uses
> "COINIT_APARTMENTTHREADED" and perhaps the caller thread uses another
> concurrency model.

Ctor of ODriver should store the previous status if COM initialization,
if it wants to re-initialize it with a specific concurrency. It should
check the failure code to detect if it was rejected because of different
mode (RPC_E_CHANGED_MODE); and if so, it should call CoUninitialize as
many times as needed to succeed with CoInitializeEx; then it needs to
additionally call CoInitializeEx the same number of times (so that the
total number of initializations is increased by 1). Then in dtor, it
should reverse that: if it hadn't needed to change mode in ctor, then
just call CoUninitialize once; otherwise, call CoUninitialize as many
times as needed to CoInitializeEx with old mode to succeed, then call
CoInitializeEx as many times that total initialize count is decremented
by 1 compared to before entering dtor. That should account for possible
intermediate unpaired calls to CoInitialize(Ex)/CoUninitialize in the
same thread, and make sure that the calling code is in ~consistent state
... (however even this is a hack, and it would be better to find out why
does it need to change the mode at all - i.e., if we can make sure it
always used in appartment-threaded code).

Best regards,
Mike Kaganski
-------------- next part --------------
A non-text attachment was scrubbed...
Name: pEpkey.asc
Type: application/pgp-keys
Size: 1769 bytes
Desc: not available
URL: <https://lists.freedesktop.org/archives/libreoffice/attachments/20200529/ca870e06/attachment.key>

More information about the LibreOffice mailing list