diff --git a/mozilla/xpcom/components/nsComponentManager.cpp b/mozilla/xpcom/components/nsComponentManager.cpp index eba6390d8c6..f054daf05a9 100644 --- a/mozilla/xpcom/components/nsComponentManager.cpp +++ b/mozilla/xpcom/components/nsComponentManager.cpp @@ -2879,11 +2879,16 @@ nsComponentManagerImpl::AutoRegisterImpl(PRInt32 when, nsIFile *inDirSpec) if (!iim) return NS_ERROR_UNEXPECTED; - + + // Startup any category observers that may want to listen to autoreg + NS_CreateServicesFromCategory("xpcom-observers", + nsnull, + NS_XPCOM_AUTOREGISTRATION_OBSERVER_ID); + // Notify observers of xpcom autoregistration start nsCOMPtr observerService = do_GetService("@mozilla.org/observer-service;1", &rv); - if (NS_FAILED(rv)) + if (NS_SUCCEEDED(rv)) { // NO COMPtr as we dont release the service manager nsIServiceManager *mgr = NS_STATIC_CAST(nsIServiceManager*, this); diff --git a/mozilla/xpcom/components/nsICategoryManager.idl b/mozilla/xpcom/components/nsICategoryManager.idl index f36830c5366..447386807b1 100644 --- a/mozilla/xpcom/components/nsICategoryManager.idl +++ b/mozilla/xpcom/components/nsICategoryManager.idl @@ -17,7 +17,7 @@ */ #include "nsISupports.idl" -#include "nsIEnumerator.idl" +#include "nsISimpleEnumerator.idl" #include "nsICategoryHandler.idl" #include "nsIFactory.idl" diff --git a/mozilla/xpcom/ds/MANIFEST_IDL b/mozilla/xpcom/ds/MANIFEST_IDL index 9b264cbffa7..50bdda2b7d8 100644 --- a/mozilla/xpcom/ds/MANIFEST_IDL +++ b/mozilla/xpcom/ds/MANIFEST_IDL @@ -7,6 +7,7 @@ nsIObserverService.idl nsIPersistentProperties2.idl nsIProperties.idl nsISerializable.idl +nsISimpleEnumerator.idl nsIStopwatch.idl nsISupportsArray.idl nsITimelineService.idl diff --git a/mozilla/xpcom/ds/Makefile.in b/mozilla/xpcom/ds/Makefile.in index eaa2e480a59..1a224b78ab8 100644 --- a/mozilla/xpcom/ds/Makefile.in +++ b/mozilla/xpcom/ds/Makefile.in @@ -113,6 +113,7 @@ XPIDLSRCS = \ nsIPersistentProperties2.idl \ nsIProperties.idl \ nsISerializable.idl \ + nsISimpleEnumerator.idl \ nsIStopwatch.idl \ nsISupportsArray.idl \ nsISupportsIterators.idl \ diff --git a/mozilla/xpcom/ds/makefile.win b/mozilla/xpcom/ds/makefile.win index f360a803d87..f9be364e602 100644 --- a/mozilla/xpcom/ds/makefile.win +++ b/mozilla/xpcom/ds/makefile.win @@ -74,6 +74,7 @@ XPIDLSRCS = \ .\nsITimelineService.idl \ .\nsIProperties.idl \ .\nsISerializable.idl \ + .\nsISimpleEnumerator.idl \ .\nsIStopwatch.idl \ .\nsISupportsArray.idl \ .\nsISupportsIterators.idl \ diff --git a/mozilla/xpcom/io/nsLocalFileMac.cpp b/mozilla/xpcom/io/nsLocalFileMac.cpp index 6a1acdee80d..3353f9e80aa 100644 --- a/mozilla/xpcom/io/nsLocalFileMac.cpp +++ b/mozilla/xpcom/io/nsLocalFileMac.cpp @@ -2485,24 +2485,23 @@ NS_IMETHODIMP nsLocalFile::GetURL(char * *aURL) rv = GetPath(&ePath); if (NS_SUCCEEDED(rv)) { - SwapSlashColon(ePath); - - // Escape the path with the directory mask - rv = nsStdEscape(ePath, esc_Directory+esc_Forced, escPath); - if (NS_SUCCEEDED(rv)) { - - escPath.Insert("file:///", 0); - - PRBool dir; - rv = IsDirectory(&dir); - NS_ASSERTION(NS_SUCCEEDED(rv), "Cannot tell if this is a directory"); - if (NS_SUCCEEDED(rv) && dir && escPath[escPath.Length() - 1] != '/') { - // make sure we have a trailing slash - escPath += "/"; - } - *aURL = nsCRT::strdup((const char *)escPath); - rv = *aURL ? NS_OK : NS_ERROR_OUT_OF_MEMORY; + SwapSlashColon(ePath); + // Escape the path with the directory mask + rv = nsStdEscape(ePath, esc_Directory+esc_Forced, escPath); + if (NS_SUCCEEDED(rv)) { + escPath.Insert("file:///", 0); + if (escPath[escPath.Length() - 1] != '/') { + PRBool dir; + rv = IsDirectory(&dir); + NS_ASSERTION(NS_SUCCEEDED(rv), "Cannot tell if this is a directory"); + if (NS_SUCCEEDED(rv) && dir) { + // make sure we have a trailing slash + escPath += "/"; + } } + *aURL = nsCRT::strdup((const char *)escPath); + rv = *aURL ? NS_OK : NS_ERROR_OUT_OF_MEMORY; + } } CRTFREEIF(ePath); return rv; diff --git a/mozilla/xpcom/io/nsLocalFileUnix.cpp b/mozilla/xpcom/io/nsLocalFileUnix.cpp index 071394d2c47..c25341ce290 100644 --- a/mozilla/xpcom/io/nsLocalFileUnix.cpp +++ b/mozilla/xpcom/io/nsLocalFileUnix.cpp @@ -1425,22 +1425,23 @@ NS_IMETHODIMP nsLocalFile::GetURL(char * *aURL) rv = GetPath(&ePath); if (NS_SUCCEEDED(rv)) { + SwapSlashColon(ePath); // Escape the path with the directory mask rv = nsStdEscape(ePath, esc_Directory+esc_Forced, escPath); if (NS_SUCCEEDED(rv)) { - - escPath.Insert("file://", 0); - - PRBool dir; - rv = IsDirectory(&dir); - NS_ASSERTION(NS_SUCCEEDED(rv), "Cannot tell if this is a directory"); - if (NS_SUCCEEDED(rv) && dir && escPath[escPath.Length() - 1] != '/') { - // make sure we have a trailing slash - escPath += "/"; + escPath.Insert("file:///", 0); + if (escPath[escPath.Length() - 1] != '/') { + PRBool dir; + rv = IsDirectory(&dir); + NS_ASSERTION(NS_SUCCEEDED(rv), "Cannot tell if this is a directory"); + if (NS_SUCCEEDED(rv) && dir) { + // make sure we have a trailing slash + escPath += "/"; + } } *aURL = ToNewCString(escPath); rv = *aURL ? NS_OK : NS_ERROR_OUT_OF_MEMORY; - } + } } CRTFREEIF(ePath); return rv; diff --git a/mozilla/xpcom/io/nsSpecialSystemDirectory.cpp b/mozilla/xpcom/io/nsSpecialSystemDirectory.cpp index 16794625270..8ba75700350 100644 --- a/mozilla/xpcom/io/nsSpecialSystemDirectory.cpp +++ b/mozilla/xpcom/io/nsSpecialSystemDirectory.cpp @@ -120,8 +120,42 @@ PR_STATIC_CALLBACK(PRBool) DeleteSystemDirKeys(nsHashKey *aKey, void *aData, voi #define NS_SYSTEMDIR_HASH_NUM (10) static nsHashtable *systemDirectoriesLocations = NULL; +#if defined (XP_WIN) +typedef BOOL (WINAPI * GetSpecialPathProc) (HWND hwndOwner, LPSTR lpszPath, int nFolder, BOOL fCreate); +GetSpecialPathProc gGetSpecialPathProc = NULL; +static HINSTANCE gShell32DLLInst = NULL; +#endif +NS_COM void StartupSpecialSystemDirectory() +{ +#if defined (XP_WIN) + /* On windows, the old method to get file locations is incredibly slow. + As of this writting, 3 calls to GetWindowsFolder accounts for 3% of mozilla + startup. Replacing these older calls with a single call to SHGetSpecialFolderPath + effectively removes these calls from the performace radar. We need to + support the older way of file location lookup on systems that do not have + IE4. + */ + gShell32DLLInst = LoadLibrary("shfolder.dll"); + if(gShell32DLLInst) + { + gGetSpecialPathProc = (GetSpecialPathProc) GetProcAddress(gShell32DLLInst, + "SHGetSpecialFolderPath"); + } + + if (!gGetSpecialPathProc) + { + if (gShell32DLLInst) + FreeLibrary(gShell32DLLInst); -NS_COM void StartupSpecialSystemDirectory(){} + gShell32DLLInst = LoadLibrary("Shell32.dll"); + if(gShell32DLLInst) + { + gGetSpecialPathProc = (GetSpecialPathProc) GetProcAddress(gShell32DLLInst, + "SHGetSpecialFolderPath"); + } + } +#endif +} NS_COM void ShutdownSpecialSystemDirectory() { @@ -130,6 +164,14 @@ NS_COM void ShutdownSpecialSystemDirectory() systemDirectoriesLocations->Reset(DeleteSystemDirKeys); delete systemDirectoriesLocations; } +#if defined (XP_WIN) + if (gShell32DLLInst) + { + FreeLibrary(gShell32DLLInst); + gShell32DLLInst = NULL; + gGetSpecialPathProc = NULL; + } +#endif } #if defined (XP_WIN) @@ -177,6 +219,25 @@ static char* MakeUpperCase(char* aPath) static void GetWindowsFolder(int folder, nsFileSpec& outDirectory) //---------------------------------------------------------------------------------------- { + + if (gGetSpecialPathProc) { + TCHAR path[MAX_PATH]; + HRESULT result = gGetSpecialPathProc(NULL, path, folder, true); + + if (!SUCCEEDED(result)) + return; + + // Append the trailing slash + int len = PL_strlen(path); + if (len>1 && path[len-1] != '\\') + { + path[len] = '\\'; + path[len + 1] = '\0'; + } + outDirectory = path; + return; + } + LPMALLOC pMalloc = NULL; LPSTR pBuffer = NULL; LPITEMIDLIST pItemIDList = NULL; diff --git a/mozilla/xpcom/tests/TestShutdown.cpp b/mozilla/xpcom/tests/TestShutdown.cpp index 64ccd5c06ac..7e66a2370f0 100644 --- a/mozilla/xpcom/tests/TestShutdown.cpp +++ b/mozilla/xpcom/tests/TestShutdown.cpp @@ -71,6 +71,9 @@ void main(int argc, char* argv[]) else { printf("Failed to create %s (%x)\n", cidStr, rv); } + + nsComponentManager::FreeLibraries(); + } rv = NS_ShutdownXPCOM(servMgr);