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
Attachment:
pEpkey.asc
Description: application/pgp-keys