Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Call CoUninitialize, if CoInitializeEx was successful. #15

Merged
merged 2 commits into from
Aug 22, 2019

Conversation

hrydgard
Copy link
Contributor

From https://docs.microsoft.com/en-us/windows/win32/api/combaseapi/nf-combaseapi-coinitializeex :

"To close the COM library gracefully on a thread, each successful call to CoInitialize or CoInitializeEx, including any call that returns S_FALSE, must be balanced by a corresponding call to CoUninitialize.".

@amodm
Copy link
Owner

amodm commented Aug 22, 2019

Thanks for the contribution, @hrydgard. I'm not very familiar with the Windows API, so can you help me understand if there are any implications stemming from the following API documentation?

CoUninitialize should be called on application shutdown, as the last call made to the COM library after the application hides its main windows and falls through its main message loop. If there are open conversations remaining, CoUninitialize starts a modal message loop and dispatches any pending messages from the containers or server for this COM application. By dispatching the messages, CoUninitialize ensures that the application does not quit before receiving all of its pending messages. Non-COM messages are discarded.

@hrydgard
Copy link
Contributor Author

Every successful CoInitialize must be matched with a CoUninitialize, otherwise the reference count will be out of whack and COM will never be unloaded even when it's possible and desired.

If an application was already using COM for something, their reference count was already 1 or more. Adding a CoUninitialize call like this will not break anything, it will only make sure that we don't "leak" reference count, like this library currently does.

@amodm
Copy link
Owner

amodm commented Aug 22, 2019

So, if I'm understanding this correctly, our CoUninitialize will get called only if we were the ones to have succeeded in calling the CoInitializeEx earlier. In case the caller had already called CoInitialize earlier in the stack, our CoInitialize fails, and thus our CoUninitialize doesn't get called. Is that correct?

@hrydgard
Copy link
Contributor Author

Yeah, pretty much. If we succeeded, we incremented the reference count and should decrement it. If we failed, a caller had already called CoInitialize with a different threading mode, and we should not decrement the count. Fortunately ShellExecute works in either threading mode so it doesn't matter for us if we failed or succeeded, we just need to do the right thing when leaving.

@amodm amodm merged commit 8c9338c into amodm:master Aug 22, 2019
@amodm
Copy link
Owner

amodm commented Aug 22, 2019

Released under 0.5.2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants