nsServiceManagerImpl::GetService(const nsCID& aClass, const nsIID& aIID,
nsServiceManagerImpl::GetService(const char* aProgID, const nsIID& aIID,
nsServiceManagerImpl::GetService(const nsCID& aClass, const nsIID& aIID,                                 nsISupports* *result,                                 nsIShutdownListener* shutdownListener){    nsresult rv = NS_OK;    /* XXX: This is a hack to force NSPR initialization..  This should be      *      removed once PR_CEnterMonitor(...) initializes NSPR... (rick)     */    (void)PR_GetCurrentThread();    PR_CEnterMonitor(this);    nsIDKey key(aClass);    nsServiceEntry* entry = (nsServiceEntry*)mServices->Get(&key);    if (entry) {        nsISupports* service;        rv = entry->mService->QueryInterface(aIID, (void**)&service);        if (NS_SUCCEEDED(rv)) {            rv = entry->AddListener(shutdownListener);            if (NS_SUCCEEDED(rv)) {                *result = service;                // If someone else requested the service to be shut down,                 // and we just asked to get it again before it could be                 // released, then cancel their shutdown request:                if (entry->mShuttingDown) {                    entry->mShuttingDown = PR_FALSE;                    NS_ADDREF(service);      // Released in UnregisterService                }            }        }    }    else {        nsISupports* service;        rv = nsComponentManager::CreateInstance(aClass, NULL, aIID, (void**)&service);        if (NS_SUCCEEDED(rv)) {            entry = new nsServiceEntry(aClass, service);            if (entry == NULL) {                NS_RELEASE(service);                rv = NS_ERROR_OUT_OF_MEMORY;            }            else {                rv = entry->AddListener(shutdownListener);                if (NS_SUCCEEDED(rv)) {                    mServices->Put(&key, entry);                    *result = service;                    NS_ADDREF(service);		// Released in service manager destructor                }                else {                    NS_RELEASE(service);                    delete entry;                }            }        }    }    PR_CExitMonitor(this);    return rv;}