> You're absolutely right here. The missing part of the picture is
> that we've never unloaded DLLs before, so it's probably the case
> that many DLLs will do bad things (crash etc) if unloaded. Certainly,
> we know that almost all of them simply return FALSE from their
> CanUnload methods. But perhaps if they were only loaded to be
> registered, then unloading would be OK.
>
> Simon
>
> --
>           Simon Fraser   Entomologist
>   [EMAIL PROTECTED]   http://people.netscape.com/sfraser/

Ah...

The system we are working on will be using XPCOM and we were thinking of
running the autoregister at the startup of the program (I guess we were
really counting on running it actually...)

So I looked into the default implementation of nsIModule (the interface
which defines the method canUnload( ).) Here are the tragic results:

NS_IMETHODIMP
nsGenericModule::CanUnload(nsIComponentManager *aCompMgr, PRBool
*okToUnload)
{
    if (!okToUnload) {
        return NS_ERROR_INVALID_POINTER;
    }
    *okToUnload = PR_FALSE;
    return NS_ERROR_FAILURE;
}

Uh oh... So no one who was built with the default will auto unload. This is
a shame because it is not that big of a deal to handle (I only say this
because ATL does it and it seems really simple, thinking of it and
implementing it might have been quite tough...) But basically in their
default implementation of AddRef and Release they increment and decrement a
global object counter per dll. This counter is only ref'd when a new
instance is created by that DLL and released when one is deleted. Then the
canUnload is just a check to see if this counter is 0 or not. I have not
been doing the XPCOM stuff for very long, so I don't know if that would work
in that system. It works really well though if everyone abides by the normal
COM type referencing (no weak references which can exist without strong
wrapping references...) I don't know if this is a fix that would be desired,
but it seems like this sort of default functionality would make XPCOM
nicer/more robust.

This is not too given my understanding that ONLY new or modified component
dlls (and deferred registration dlls) are loaded at auto-registration time.
Therefore only a few components will be always loaded into memory due to
this (the crummy thing is that these components might never be used, and
therefore become a memory bloat for the whole app.) I'm not sure how big of
a deal this is for Mozilla itself.

I also noticed when running around the standard NS_IMPL_ADDREF and RELEASE
macros that they do not do a thread safe increment and decrement on the
internal ref count. For example:

#define NS_IMPL_ADDREF(_class)                               \
NS_IMETHODIMP_(nsrefcnt) _class::AddRef(void)                \
{                                                            \
  NS_PRECONDITION(PRInt32(mRefCnt) >= 0, "illegal refcnt");  \
  NS_ASSERT_OWNINGTHREAD(_class);                            \
  ++mRefCnt;                                                 \
  NS_LOG_ADDREF(this, mRefCnt, #_class, sizeof(*this));      \
  return mRefCnt;                                            \
}

Now I do not know what sort of multi threaded stuff is allowed or intended
for XPCOM, but again under COM this would be a big no-no unless you were
implementing purely single-threaded objects. Maybe this is the case for most
of the XPCOM stuff, but it surprises me that there is an
NS_ASSERT_OWNINGTHREAD( ) call, and then it does not bother to do safe
increments and decrements (but I'm probably missing something here...)

Ken



Reply via email to