FreeLibrary and DLLMain

Now, I have a DLL (DLL A) that calls a second DLL (DLL B) to build a function upcall table.  These functions are used throughout the life of DLL A by other external processes.  Now, my question is...  since this upcall table needs to be valid for the lifetime of DLL A, how can I free the reference to DLL B since I cannot call FreeLibrary from DllMain during PROCESS_DETACH?

I do not have access to the other applications that use this upcall table, so the idea of having a special function called prior to unload that would clean everything up isn't going to work.

How can I cleanly unload DLL B when DLL A is about to exit?
LVL 1
guitarmanchuAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

aib_42Commented:
I'm not sure why exactly calling LoadLibrary/FreeLibrary from DllMain is a problem, but if it's only to prevent deadlocks due to dependencies/freeing orders, you might just get away with calling FreeLibrary, probably with even more luck if A is the only module getting unloaded (i.e. DLL_PROCESS_DETACH was signalled due to FreeLibrary(A), lpvReserved=NULL)

I was going to suggest having B free itself (with a call from A), but if you stick to the API documentation, you are not supposed to call functions that may call functions that may call FreeLibrary... Which, as far as I understand, means you HAVE TO free B before or after A's DllMain is called.

I would suggest allocating some executable memory (VirtualAlloc?), populating it with the 6-byte code needed to free B and exit, and calling it using CreateThread...only if it wasn't a horrible, horrible hack.
0
i_maheshCommented:
you can make use of thread synchronization using events or posting message to a thread using PostThreadMessage API and listen for the event / message in a thread in DLL B and unload the DLL when you receive the event / message.
0
DFPercushCommented:
Create a monitor thread when DLL_A is loaded and have it clean up DLL_B for you:

void Monitor(LPVOID hWaitableObject)
{
WaitForSingleObject(hWaitableObject);
//Sleep(1);  SwitchToThread();  // Optional
FreeLibrary(hDLL_B);
}

// You will have to know hDLL_B somehow, or pass it in a structure when creating the thread.

BOOL DllMain( HINSTANCE hinstDLL,
  DWORD fdwReason,
  LPVOID lpvReserved)
{
    DWORD monitor_thread;
    if (fdwReason == PROCESS_ATTACH)
    {
           CreateThread(NULL, 500, Monitor, hInstDll, 0, &monitor_thread);
           // OR:  CreateThread(NULL, 500, Monitor, GetCurrentThread(), 0, &monitor_thread);
    }
}

//--------------------------------------------------------------
// If that does not work, you could use a system event object and manually signal it

BOOL DllMain( HINSTANCE hinstDLL,
  DWORD fdwReason,
  LPVOID lpvReserved)
{
    DWORD monitor_thread;
    HANDLE hEvent;
    if (fdwReason == PROCESS_ATTACH)
    {
            hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
           CreateThread(NULL, 500, Monitor, hEvent, 0, &monitor_thread);
     }
    else if (fdwReason == PROCESS_DETACH)
    {
            PulseEvent(hEvent);
    }
}
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
DFPercushCommented:
WaitForSingleObject() takes 2 parameters, my mistake. The second is a time-out in ms, and I would recommend setting it to INFINITE.

WaitForSingleObject(hWaitableObject, INFINITE);
0
guitarmanchuAuthor Commented:
Fantastic answer, thanks!
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Programming

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.