implementing DllCanUnloadNow questions

Robert Shearman rob at codeweavers.com
Tue Nov 30 15:34:50 CST 2004


James Hawkins wrote:

>I would like to work on the DllCanUnloadNow janitorial task, but I was
>wondering if there are any patches or examples of dll's that correctly
>implement this so that I can do it right.
>  
>

I don't know of any examples so far, but Mike Hearn and I will be 
tackling OLE soon, so that will involve cleaning up ole32. However, that 
probably won't happen until we've done some groundwork on COM first, so 
feel free to beat us to it and make a shining example of a DLL that 
correctly implements DllCanUnloadNow.

>Is LockServer(TRUE/FALSE) the same as this example?
>
>static HRESULT WINAPI SFCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
>       IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
>       FIXME("(%p)->(%d),stub!\n",This,dolock);
>       return S_OK;
>}
>
>If they are the same, what is needed to complete this stub?  I would
>think that there would be a refCount variable that is incremented if
>dolock is true and decremented if dolock is false.  Also, should the
>LockServer functions be listed in the spec files of the dlls?
>  
>

No, the LockServer functions are part of IClassFactory vtables. Only 
DllCanUnloadNow needs to be exported.

>After implementing LockServer, it should be an easy matter to do a
>check for refCount == 0 to see if the dll can be unloaded or not.  Am
>I heading in the right direction?
>  
>

To implement DllCanUnloadNow properly you need to do the following:
1. Add a variable "LONG cLocks" and two function for manipulating it:
void LockModule()
{
    InterlockedIncrement(&cLocks);
}

void UnlockModule()
{
    InterlockedDecrement(&cLocks);
}
2. Increment cLocks on construction of every heap object:
static HRESULT Example_Construct(...)
{
...
    LockModule();
    return S_OK;
}
3. Decrement cLocks on destruction of every heap object:
static ULONG Example_Release(...)
{
    ...
    res = InterlockedDecrement(&This->cRefs);
    if (!res)
    {
       /* Free object's resources, including memory, etc. */
       UnlockModule();
    }
}
4. For non-heap based objects (commonly objects with no state, like 
IClassFactory):
static ULONG Example_AddRef(...)
{
    LockModule();
    return 2; /* non-heap object */
}

static ULONG Example_Release(...)
{
    UnlockModule();
    return 1;
}
5. Implement IClassFactory_LockServer's as follows:
HRESULT WINAPI Example_LockServer(...)
{
    if (bLock)
       LockModule();
    else
       UnlockModule();
    return S_OK;
}
6. Then implement DllCanUnloadNow:
HRESULT WINAPI DllCanUnloadNow()
{
    return cLocks > 0 : S_FALSE : S_OK;
}

Rob



More information about the wine-devel mailing list