views:

43

answers:

2

While trying to resolve process hanging on CoUninitialize() I came upon a piece of code shared by many of our projects. When a program is going to quit it first calls CoFreeUnusedLibraries(), then immediately OleUninitialize().

While the effect of OleUninitialize() is quite clear I can't find why one would want to call CoFreeUnusedLibraries() before calling OleUnitialize(). What might be the use of this call at this specific point?

A: 

Docs indicate that

This function is provided for compatibility with 16-bit Windows.

Hmmm...

Have you seen this problem report? This call seems redundant to me - maybe this leaves one or more DLLs in a state where OleUninitialize does not work properly - waiting for some state change due to the earlier call. However this does allude to the need to wait a while between calls...

CoFreeUnusedLibraries does not immediately release DLLs that have no active object. There is a ten minute delay for multithreaded apartments (MTAs) and neutral apartments (NAs). For single-threaded apartments (STAs), there is no delay. The ten minute delay for CoFreeUnusedLibraries is to avoid multithread race conditions caused by unloading a component DLL.

There are also comments elsewhere re a 6 -minute closedown timeout when using DCOM - is that applicable to you?

Steve Townsend
A: 

CoFreeUnusedLibraries() will trigger a call to the DllCanUnloadNow for each in-process COM DLL that exports this function. Not sure about threading issues or out-of-process COM components as it relates to this API.

Presumably, someone who wrote the code that calls DllCanUnloadNow before OleUnitialize was attempting to reduce working set and ensure cleanup.

I don't think there's much value in calling CoFreeUnusedLibraries right before application shutdown (the DLLs will get unloaded anyway).

My experience is that calling CoFreeUnusedLibraries results in crashes and hangs in 3rd party COM DLLs that never had their DllCallUnloadNow implementation tested before release. (Because not too many apps call this function).

You didn't provide a call stack or hint as to where the hang was occurring (did you break into a debugger to see what DLL is at the top of the stack?). My guess is that you can likely take this call out if you can't fix the offending DLL.

selbie