0

In my C application, I have a child thread that retrieve a IUnknown interface at beginning of his life :

static struct IUnknown* punk = NULL;

void DispatcherStart(){
    CoInitialize(NULL);
    CheckHRESULT(GetActiveObject(&MY_CLSID,NULL,&punk));
}

everything is fine, it's used to invoke some activeX functions and it work ! however, when my program end, it ask the thread to terminate, so my thread call is ending function's :

void DispatcherStop(){
    if(punk) (punk)->lpVtbl->Release(punk); // BLOCK here
    punk = NULL;
    CoUninitialize();
}

my thead never return because Release on my IUnknow ptr block it. (if I remove the Release then the COUnitialize() block too)

What I am doing wrong ? (the punk iniatilisation can't be done in main thread)

Xemuth
  • 415
  • 3
  • 12
  • 1
    Not a lot of info to go on. My experience is that GetActiveObject() is usually called for an out of process object. In the case of an out of process object, I would think your Release() would be blocked until a timeout...probably 30 seconds. After the timeout, it would return. I did notice that GetActiveObject() is declared in oleauto.h. In general, there isn't a lot of difference between CoInitialize() and OleInitialize(), but there may be some. I might try using the OLE functions OleInitialize(NULL) and OleUnitiaize() instead of the "Co" versions. – Joseph Willcoxson Jan 12 '21 at 16:34
  • @JosephWillcoxson Thanks for your help, No difference between Ole and Co version. Both keep block my thread and I have to set a timeout to close my app correctly. – Xemuth Jan 12 '21 at 16:44
  • @JosephWillcoxson not a lot info indeed. My code is very simple at the moment. my thread initialize OLE via oleInit / CoInit and then directly. To give more context, I'm working on a base code which init an ActiveX server then launch my child thread which is connecting to this activeX server. when it come to the end, my thread is release before releasing the activeX serveur. – Xemuth Jan 12 '21 at 16:48
  • if I try to init my IUnknown ptr from main thread then some activeX function do nothing (all activeX function that work on GUI) and some work. The release and OleUninit work and don't block – Xemuth Jan 12 '21 at 16:55
  • 1
    OleUnitialize is required for some operations, like the Clipboard, Drag & Drop, etc. That doesn't seem to be needed in your case. An STA thread (stared by CoInitialize) like you have must pump a message loop https://learn.microsoft.com/en-us/windows/win32/com/single-threaded-apartments . Your Release call sends a message to a message loop that doesn't (seem to) pump messages. – Simon Mourier Jan 12 '21 at 19:28
  • indeed, removing CoUnitialize and Release call fix the problem, I can still acquiere my IUnknown ptr – Xemuth Jan 13 '21 at 09:57

1 Answers1

1

thread that does CoInitialize will fail if it hasn't message pump. So use CoInitializeEx(NULL,COINIT_MULTITHREADED); if thread doesn't have own one.
But latter case is only for mta com's.
And this doesn't mean you'll just change CoInitialize to CoInitializeEx..
mta com should have own base. And you should provide it. like i've done there https://github.com/alexeyneu/tool3/blob/00bfd2aaf2973626f166ea754b756fd0f2fa0d0b/tool3/MainFrm.cpp#L254