Re: QueueUserWorkItem with functions in a DLL, how to unload safely?
- From: "Skywing" <skywing_NO_SPAM_@xxxxxxxxxxxxxxxxxxx>
- Date: Fri, 27 Jan 2006 13:26:15 -0500
Well, that's a tricky thing to solve. The easiest way to do it is to wrap
the call to the DLL-provided work item routine in a function that will
always remain loaded (such as a function present in the main .exe for the
process).
For example, you might have the .exe export a QueueUserWorkItem-type
function to the DLL. This function would call QueueUserWorkItem internally,
but instead of passing the ThreadProc/Context directly to QueueUserWorkItem,
it would instead pass the address of a wrapper function and a structure that
contains the original function to call and the original context.
For example... (assume this code resides in the main .exe image and plugin
DLLs call into MyQueueUserWorkItem to queue a work item - this code would in
reality need to track reference counts on a per dll basis and not globally,
but that's specific to your implementation so I just used a global reference
count to get the idea across):
VOID CheckForDllUnload()
{
/*
* Check for dlls that requested to be unloaded now and have a zero
* reference count.
*/
.
.
.
}
ULONG g_WorkItemsActive = 0;
typedef struct _MY_CONTEXT
{
ThreadProc OriginalThreadProc;
PVOID OriginalContext;
} MY_CONTEXT, * PMY_CONTEXT;
DWORD WINAPI MyThreadProc(LPVOID lpParameter)
{
PMY_CONTEXT Ctx = reinterpret_cast<PMY_CONTEXT>(lpParameter);
DWORD Status;
Status = Ctx->OriginalThreadProc(Ctx->OriginalContext);
HeapFree(GetProcessHeap(), 0, Ctx);
/*
* Drop the reference we took during MyQueueUserWorkItem and do unload
handling here if
* the references dropped to zero.
*/
if(!InterlockedDecrement(&g_WorkItemsActive))
CheckForDllUnload();
return Status;
}
BOOL WINAPI MyQueueUserWorkItem(LPTHREAD_START_ROUTINE Function, PVOID
Context, ULONG Flags)
{
PMY_CONTEXT Ctx = (PMY_CONTEXT)HeapAlloc(GetProcessHeap(), 0,
sizeof(MY_CONTEXT));
if(!Ctx)
return FALSE;
Ctx->OriginalThreadProc = Function;
Ctx->OriginalContext = Context;
/*
* In reality this should increment a per-plugin-dll reference count, you
would probably
* want to pass some kind of identifier from the plugin dll to this
function that would
* be used internally to identify the plugin dll instance so you could add
a reference
* to it and support unloading if the refcount drops to zero.
*
* For illustration purposes this just uses a global reference count
instead of a per-dll
* one.
*/
InterlockedIncrement(&g_WorkItemsActive);
if(!QueueUserWorkItem(MyThreadProc, Ctx, Flags))
{
HeapFree(GetProcessHeap(), 0, Ctx);
/*
* If we failed to queue here then kill the reference and check for dll
unloading.
* Otherwise, if QueueUserWorkItem succeeds, then the reference will be
released
* when the work item returns from the plugin dll.
*/
if(!InterlockedDecrement(&g_WorkItemsActive))
CheckForDllUnload();
return FALSE;
}
return TRUE;
}
"Stefan Kuhr" <kustt110@xxxxxx> wrote in message
news:ueLg4EzIGHA.1760@xxxxxxxxxxxxxxxxxxxxxxx
> Hello everyone,
>
> I want to create a thread pool in a DLL's function and pass adresses of
> functions in the DLL as the ThreadProc parameter of QueueUserWorkItem. The
> DLL is part of a Plugin-Concept and will ultimately have to be unloaded at
> some point, using FreeLibrary. However, the documentation of
> QueueUserWorkItem says:
>
> "If a function in a DLL is queued to a worker thread, be sure that the
> function has completed execution before the DLL is unloaded."
>
> How is it possible to guarantee this condition so I can do a safe
> FreeLibrary on the DLL? What programming techniques can be employed for
> that?
>
> --
> Stefan Kuhr
.
- Follow-Ups:
- Re: QueueUserWorkItem with functions in a DLL, how to unload safely?
- From: Stefan Kuhr
- Re: QueueUserWorkItem with functions in a DLL, how to unload safely?
- From: Pavel Lebedinsky [MSFT]
- Re: QueueUserWorkItem with functions in a DLL, how to unload safely?
- References:
- QueueUserWorkItem with functions in a DLL, how to unload safely?
- From: Stefan Kuhr
- QueueUserWorkItem with functions in a DLL, how to unload safely?
- Prev by Date: Re: ReadProcessMemory from DOS program
- Next by Date: Remote Debugging for Winlogon
- Previous by thread: Re: QueueUserWorkItem with functions in a DLL, how to unload safely?
- Next by thread: Re: QueueUserWorkItem with functions in a DLL, how to unload safely?
- Index(es):
Relevant Pages
|