implementing DllCanUnloadNow questions
James Hawkins
truiken at gmail.com
Tue Nov 30 17:33:20 CST 2004
On Tue, 30 Nov 2004 15:34:50 -0600, Robert Shearman <rob at codeweavers.com> wrote:
> 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
>
Attached is my beginning attempts at adding DllCanUnloadNow to msi.
There are a couple questions I have though.
> static HRESULT Example_Construct(...)
> {
> ...
> LockModule();
> return S_OK;
> }
Is _Construct the same as _AddRef()? I'm thinking it's not. If it
isn't, I need to add a MSI_Construct to msi. What are the parameters
to the Construct function and what would usually go in the place of
the "..."?
> static ULONG Example_Release(...)
> {
> ...
> res = InterlockedDecrement(&This->cRefs);
> if (!res)
> {
> /* Free object's resources, including memory, etc. */
> UnlockModule();
> }
> }
> static ULONG Example_Release(...)
> {
> UnlockModule();
> return 1;
> }
Are these _Release's referring to the same function? If not, what is
the difference? If so, which one should be implemented and what
usually goes in the place of the "..."?
--
James Hawkins
-------------- next part --------------
A non-text attachment was scrubbed...
Name: msi-dllcanunloadnow.diff
Type: text/x-patch
Size: 1136 bytes
Desc: not available
Url : http://www.winehq.org/pipermail/wine-devel/attachments/20041130/9e4c2883/msi-dllcanunloadnow.bin
More information about the wine-devel
mailing list