Back to index

lightning-sunbird  0.9+nobinonly
Classes | Functions | Variables
nsNativeComponentLoader.cpp File Reference
#include "prmem.h"
#include "prerror.h"
#include "prsystem.h"
#include "nsNativeComponentLoader.h"
#include "nsComponentManager.h"
#include "nsCOMPtr.h"
#include "nsIServiceManager.h"
#include "nsIModule.h"
#include "xcDll.h"
#include "nsHashtable.h"
#include "nsXPIDLString.h"
#include "nsCRT.h"
#include "nsIObserverService.h"
#include "prlog.h"

Go to the source code of this file.

Classes

struct  freeLibrariesClosure

Functions

static PRBool PR_CALLBACK DLLStore_Destroy (nsHashKey *aKey, void *aData, void *closure)
 NS_IMPL_THREADSAFE_ISUPPORTS1 (nsNativeComponentLoader, nsIComponentLoader) NS_IMETHODIMP nsNativeComponentLoader
static nsresult PR_CALLBACK nsFreeLibrary (nsDll *dll, nsIServiceManager *serviceMgr, PRInt32 when)
static PRBool PR_CALLBACK nsFreeLibraryEnum (nsHashKey *aKey, void *aData, void *closure)

Variables

NS_COM PRLogModuleInfonsComponentManagerLog

Class Documentation

struct freeLibrariesClosure

Definition at line 347 of file nsNativeComponentLoader.cpp.

Collaboration diagram for freeLibrariesClosure:
Class Members
nsIServiceManager * serviceMgr
PRInt32 when

Function Documentation

static PRBool PR_CALLBACK DLLStore_Destroy ( nsHashKey *  aKey,
void aData,
void closure 
) [static]

Definition at line 73 of file nsNativeComponentLoader.cpp.

{
    nsDll* entry = NS_STATIC_CAST(nsDll*, aData);
    delete entry;
    return PR_TRUE;
}

Definition at line 87 of file nsNativeComponentLoader.cpp.

{
    nsresult rv;

    if (!_retval)
        return NS_ERROR_NULL_POINTER;
    
    /* use a hashtable of WeakRefs to store the factory object? */

    /* Should this all live in xcDll? */
    nsDll *dll;
    rv = CreateDll(nsnull, aLocation, &dll);
    if (NS_FAILED(rv))
        return rv;

    if (!dll)
        return NS_ERROR_OUT_OF_MEMORY;

    if (!dll->IsLoaded()) {
#ifdef PR_LOGGING
        nsXPIDLCString displayPath;
        dll->GetDisplayPath(displayPath);

        PR_LOG(nsComponentManagerLog, PR_LOG_DEBUG,
               ("nsNativeComponentLoader: loading \"%s\"",
                displayPath.get()));
#endif
        if (!dll->Load()) {

            PR_LOG(nsComponentManagerLog, PR_LOG_ALWAYS,
                   ("nsNativeComponentLoader: load FAILED"));
        
            char errorMsg[1024] = "<unknown; can't get error from NSPR>";

            if (PR_GetErrorTextLength() < (int) sizeof(errorMsg))
                PR_GetErrorText(errorMsg);

            DumpLoadError(dll, "GetFactory", errorMsg);

            return NS_ERROR_FAILURE;
        }
    }

    /* Get service manager for factory */
    nsCOMPtr<nsIServiceManager> serviceMgr;
    rv = NS_GetServiceManager(getter_AddRefs(serviceMgr));
    if (NS_FAILED(rv))
        return rv;      // XXX translate error code?
    
    rv = GetFactoryFromModule(dll, aCID, _retval);

    PR_LOG(nsComponentManagerLog, NS_SUCCEEDED(rv) ? PR_LOG_DEBUG : PR_LOG_ERROR,
           ("nsNativeComponentLoader: Factory creation %s for %s",
            (NS_SUCCEEDED(rv) ? "succeeded" : "FAILED"),
            aLocation));

    // If the dll failed to get us a factory. But the dll registered that
    // it would be able to create a factory for this CID. mmh!
    // We cannot just delete the dll as the dll could be hosting
    // other CID for which factory creation can pass.
    // We will just let it be. The effect will be next time we try
    // creating the object, we will query the dll again. Since the
    // dll is loaded, this aint a big hit. So for optimized builds
    // this is ok to limp along.
    NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Factory creation failed");
    
    return rv;
}

Here is the call graph for this function:

static nsresult PR_CALLBACK nsFreeLibrary ( nsDll dll,
nsIServiceManager serviceMgr,
PRInt32  when 
) [static]

Definition at line 254 of file nsNativeComponentLoader.cpp.

{
    nsresult rv = NS_ERROR_FAILURE;

    if (!dll || dll->IsLoaded() == PR_FALSE)
    {
        return NS_ERROR_INVALID_ARG;
    }

    // Get if the dll was marked for unload in an earlier round
    PRBool dllMarkedForUnload = dll->IsMarkedForUnload();

    // Reset dll marking for unload just in case we return with
    // an error.
    dll->MarkForUnload(PR_FALSE);

    PRBool canUnload = PR_FALSE;

    // Get the module object
    nsCOMPtr<nsIModule> mobj;
    /* XXXshaver cheat and use the global component manager */
    rv = dll->GetModule(NS_STATIC_CAST(nsIComponentManager*, nsComponentManagerImpl::gComponentManager),
                        getter_AddRefs(mobj));
    if (NS_SUCCEEDED(rv))
    {
        rv = mobj->CanUnload(nsComponentManagerImpl::gComponentManager, &canUnload);
    }

    mobj = nsnull; // Release our reference to the module object
    // When shutting down, whether we can unload the dll or not,
    // we will shutdown the dll to release any memory it has got
    if (when == nsIComponentManagerObsolete::NS_Shutdown)
    {
        dll->Shutdown();
    }
        
    // Check error status on CanUnload() call
    if (NS_FAILED(rv))
    {
#ifdef PR_LOGGING
        nsXPIDLCString displayPath;
        dll->GetDisplayPath(displayPath);

        PR_LOG(nsComponentManagerLog, PR_LOG_ERROR,
               ("nsNativeComponentLoader: nsIModule::CanUnload() returned error for %s.",
                displayPath.get()));
#endif
        return rv;
    }

    if (canUnload)
    {
        if (dllMarkedForUnload)
        {
#ifdef PR_LOGGING
            nsXPIDLCString displayPath;
            dll->GetDisplayPath(displayPath);

            PR_LOG(nsComponentManagerLog, PR_LOG_DEBUG, 
                   ("nsNativeComponentLoader: + Unloading \"%s\".", displayPath.get()));
#endif

#ifdef DEBUG_dougt
            // XXX dlls aren't counting their outstanding instances correctly
            // XXX hence, dont unload until this gets enforced.
            rv = dll->Unload();
#endif /* 0 */
        }
        else
        {
#ifdef PR_LOGGING
            nsXPIDLCString displayPath;
            dll->GetDisplayPath(displayPath);

            PR_LOG(nsComponentManagerLog, PR_LOG_DEBUG,
                   ("nsNativeComponentLoader: Ready for unload \"%s\".", displayPath.get()));
#endif
        }
    }
    else
    {
#ifdef PR_LOGGING
        nsXPIDLCString displayPath;
        dll->GetDisplayPath(displayPath);

        PR_LOG(nsComponentManagerLog, PR_LOG_WARNING, 
               ("nsNativeComponentLoader: NOT ready for unload %s", displayPath.get()));
#endif
        rv = NS_ERROR_FAILURE;
    }
    return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PRBool PR_CALLBACK nsFreeLibraryEnum ( nsHashKey *  aKey,
void aData,
void closure 
) [static]

Definition at line 354 of file nsNativeComponentLoader.cpp.

{
    nsDll *dll = (nsDll *) aData;
    struct freeLibrariesClosure *callData = (struct freeLibrariesClosure *) closure;
    nsFreeLibrary(dll,
                  (callData ? callData->serviceMgr : NULL),
                  (callData ? callData->when : nsIComponentManagerObsolete::NS_Timer));
    return PR_TRUE;
}

Here is the call graph for this function:


Variable Documentation

Definition at line 98 of file nsComponentManager.cpp.