15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


CoFreeUnusedLibraries() hangs on Win 95

Joshua Cohen -- Joshua_Cohen@msn.com
Tuesday, November 12, 1996

Environment : Visual C++ 4.2-flat, Win 95.

My application is hanging inside CoFreeUnusedLibraries(), which is part of 
OLE32.  This function has been called by MFC's AfxOleTermOrFreeLib(), called 
by AfxUnlockTempMaps(), called by AfxTermThread(), called by DllMain().  
DllMain() has been called because a thread created by an OCX has terminated.

I found that there have been a couple of updates to Windows 95's OLE32.DLL, so 
I got the later one and applied it, which did not help.  It is dated January 
25, 1996.

These are the main possibilities I can think of: 1) Because the OCX is 
multi-threaded, it has special responsibilities that it is not fulfilling.  2) 
The OCX has some other problem, unrelated to threads.  3)  There's an MFC 
problem.  4) There's a problem with CoFreeUnusedLibraries() itself.

I believe I can work around the symptom by letting the thread live until the 
end, and simply enabling and disabling its action, rather than by creating and 
destroying it.  However, I'm concerned that I might simply be masking some 
underlying problem.

Does anyone have an idea why CoFreeUnusedLibraries() might hang?



John -- John.Weeder@abii.com
Tuesday, November 12, 1996

[Mini-digest: 2 responses]

First of all, I would suspect a logic flaw in your program (or the COM 
objects)... not necessarily one of the possibilities you list. 

I suspect that the lock count on one of your COM objects is not being 
maintained correctly. If the lock count accidently reaches 0, a call to 
CoFreeUnusedLibraries() may release your DLL and the next access to the 
object will fail unpredictably. 

Here is how to diagnose this problem:

1) Locate the DllCanUnloadNow() function in each of your in-proc 
servers. Place a call to OutputDebugString("text...") in each function; 
similar to the following:

STDAPI DllCanUnloadNow(void)
{
   AFX_MANAGE_STATE(AfxGetStaticModuleState());
   HRESULT hr = AfxDllCanUnloadNow();
   char szDebug[512];
   wsprintf(szDebug, "Module: DllCanUnloadNow=%08lX\r\n", hr);
   OutputDebugString(szDebug);
   return hr;
}

OutputDebugString() is a kind of printf() for Windows which will place 
some text in the output window notifying you when a DLL is going 
bye-bye.

2) Sprinkle you code liberally with '#ifdef _DEBUG'ed calls to 
CoFreeUnusedLibraries(). This will causes calls to all the 
DllCanUnloadNow() functions.  

3) Make sure the none of your DLL's are signalling they can be unloaded 
when, in fact, you still have active object.



Also, check all of your DLL entry points and make absolutely sure they 
are gaurded with either the AFX_MANAGE_STATE macro or the 
METHOD_PROLOGUE macro.

----------
From: 	Joshua Cohen
Sent: 	Monday, November 11, 1996 6:29 PM
To: 	MFCList
Subject: 	CoFreeUnusedLibraries() hangs on Win 95

Environment : Visual C++ 4.2-flat, Win 95.

My application is hanging inside CoFreeUnusedLibraries(), which is part 
of 
OLE32.  This function has been called by MFC's AfxOleTermOrFreeLib(), 
called 
by AfxUnlockTempMaps(), called by AfxTermThread(), called by DllMain(). 
 
DllMain() has been called because a thread created by an OCX has 
terminated.

I found that there have been a couple of updates to Windows 95's OLE32.  
DLL, so 
I got the later one and applied it, which did not help.  It is dated 
January 
25, 1996.

These are the main possibilities I can think of: 1) Because the OCX is 
multi-threaded, it has special responsibilities that it is not 
fulfilling.  2) 
The OCX has some other problem, unrelated to threads.  3)  There's an 
MFC 
problem.  4) There's a problem with CoFreeUnusedLibraries() itself.

I believe I can work around the symptom by letting the thread live 
until the 
end, and simply enabling and disabling its action, rather than by 
creating and 
destroying it.  However, I'm concerned that I might simply be masking 
some 
underlying problem.

Does anyone have an idea why CoFreeUnusedLibraries() might hang?

-----From: Mike Blaszczak 

At 00:29 11/12/96 UT, Joshua Cohen wrote:
>Environment : Visual C++ 4.2-flat, Win 95.

Please upgrade to 4.2b.

>My application is hanging inside CoFreeUnusedLibraries(), which is part of 
>OLE32.  This function has been called by MFC's AfxOleTermOrFreeLib(), called 
>by AfxUnlockTempMaps(), called by AfxTermThread(), called by DllMain().  
>DllMain() has been called because a thread created by an OCX has terminated.

>These are the main possibilities I can think of: 1) Because the OCX is 
>multi-threaded, it has special responsibilities that it is not fulfilling.  2) 
>The OCX has some other problem, unrelated to threads.  3)  There's an MFC 
>problem.  4) There's a problem with CoFreeUnusedLibraries() itself.

It's actually a combination of 3) and 4).  When you call
CoFreeUnusedLibraries(),
you might be causing some libraries to unload.  If a library unloads, Windows
internally gains a critical section to remind itself that it can't do certain
operations.  In the MFC DLLs, we were previously calling CoFreeUnusedLibraries()
in DLL_PROCESS_DETACH and DLL_THREAD_DETACH.  That's bad, because at that time
Windows has the critical section locked because it is unloading and loading
modules.  If you cause another module to unload at the same time (eg,
by calling CoFreeUnusedLibraries()) you'll end up causing Windows to deadlock.

MFC's involvement in this problem was addressed in the 4.2b patch.  If you're
calling these APIs directly yourself, you need to watch out for the same issues.

.B ekiM
http://www.nwlink.com/~mikeblas/
I'm afraid I've become some sort of speed freak.
These words are my own. I do not speak on behalf of Microsoft.





| Вернуться в корень Архива |