Re: QueueUserWorkItem with functions in a DLL, how to unload safely?

Tech-Archive recommends: Fix windows errors by optimizing your registry



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


.



Relevant Pages

  • VB FAQs (Interview Questions) lot lot
    ... Consider two objects, A and B. A holds a reference to B, ... Why do so many example programs not use the DLL name ... Private Declare Function SendMessage Lib "user32" ... Private Const BUFFER_LENGTH As Long = 255 ...
    (microsoft.public.dotnet.languages.vb)
  • Re: Sharing Code
    ... What I found would happen is that when the device dll was built visual ... In the desktop project when you add a reference to the dll, ... > projects, one smart device and one desktop, but they're in the same ... > The 2 form projects have references to this class library projects. ...
    (microsoft.public.dotnet.framework.compactframework)
  • Re: Namespaces - broad question
    ... Reference the Class Library in your Page, ... > aspx pages that I know I want utilize a specific function within, ... > have the same codebehind page), how can I reference this function. ... >> A .Net assembly is a compiled DLL. ...
    (microsoft.public.dotnet.framework.aspnet)
  • Re: Namespace Question
    ... >>i saw that when i changed it to true my dll was copied to the bin folder ... >>the reference by looking in the following locations, ... Look for assemblies in directories specified with the Reference Path ... >> tried to use the GAC but the process to convert dll to be strong name ...
    (microsoft.public.dotnet.languages.vb)
  • Re: calling from one workbook the classes and functions in another
    ... having discovered the vb trick recently I'm suddenly a big fan ... > reference to the instantiated class. ... you can't instantiate the class. ... >> Copy your cls into a VB Project for an activex dll. ...
    (microsoft.public.excel.programming)