зеркало из https://github.com/mozilla/pjs.git
Bug 296430, part "xpcom" - Add a category for directory-service providers which will be registered after autoregistration but before xpcom-startup r=darin a=asa
This commit is contained in:
Родитель
4d1c86ee60
Коммит
591acc2faa
|
@ -258,6 +258,56 @@ NS_Realloc(void* ptr, PRSize size);
|
|||
extern "C" NS_COM void
|
||||
NS_Free(void* ptr);
|
||||
|
||||
|
||||
/**
|
||||
* Categories (in the category manager service) used by XPCOM:
|
||||
*/
|
||||
|
||||
/**
|
||||
* A category which is read after component registration but before
|
||||
* the "xpcom-startup" notifications. Each category entry is treated
|
||||
* as the contract ID of a service which implements
|
||||
* nsIDirectoryServiceProvider. Each directory service provider is
|
||||
* installed in the global directory service.
|
||||
*
|
||||
* @status FROZEN
|
||||
*/
|
||||
#define XPCOM_DIRECTORY_PROVIDER_CATEGORY "xpcom-directory-providers"
|
||||
|
||||
/**
|
||||
* A category which is read after component registration but before
|
||||
* NS_InitXPCOM2 returns. Each category entry is treated as the contractID of
|
||||
* a service: each service is instantiated, and if it implements nsIObserver
|
||||
* the nsIObserver.observe method is called with the "xpcom-startup" topic.
|
||||
*
|
||||
* @status FROZEN
|
||||
*/
|
||||
#define NS_XPCOM_STARTUP_CATEGORY "xpcom-startup"
|
||||
|
||||
|
||||
/**
|
||||
* Observer topics (in the observer service) used by XPCOM:
|
||||
*/
|
||||
|
||||
/**
|
||||
* At XPCOM startup after component registration is complete, the
|
||||
* following topic is notified. In order to receive this notification,
|
||||
* component must register their contract ID in the category manager,
|
||||
*
|
||||
* @see NS_XPCOM_STARTUP_CATEGORY
|
||||
* @status FROZEN
|
||||
*/
|
||||
#define NS_XPCOM_STARTUP_OBSERVER_ID "xpcom-startup"
|
||||
|
||||
/**
|
||||
* At XPCOM shutdown, this topic is notified. All components must
|
||||
* release any interface references to objects in other modules when
|
||||
* this topic is notified.
|
||||
*
|
||||
* @status FROZEN
|
||||
*/
|
||||
#define NS_XPCOM_SHUTDOWN_OBSERVER_ID "xpcom-shutdown"
|
||||
|
||||
extern "C" NS_COM nsresult
|
||||
NS_GetDebug(nsIDebug* *result);
|
||||
|
||||
|
|
|
@ -242,18 +242,10 @@ RegisterGenericFactory(nsIComponentRegistrar* registrar,
|
|||
static PRBool CheckUpdateFile()
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIProperties> directoryService;
|
||||
nsDirectoryService::Create(nsnull,
|
||||
NS_GET_IID(nsIProperties),
|
||||
getter_AddRefs(directoryService));
|
||||
|
||||
if (!directoryService)
|
||||
return PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIFile> file;
|
||||
rv = directoryService->Get(NS_XPCOM_CURRENT_PROCESS_DIR,
|
||||
NS_GET_IID(nsIFile),
|
||||
getter_AddRefs(file));
|
||||
rv = nsDirectoryService::gService->Get(NS_XPCOM_CURRENT_PROCESS_DIR,
|
||||
NS_GET_IID(nsIFile),
|
||||
getter_AddRefs(file));
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Getting NS_XPCOM_CURRENT_PROCESS_DIR failed");
|
||||
|
@ -268,9 +260,9 @@ static PRBool CheckUpdateFile()
|
|||
return PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIFile> compregFile;
|
||||
rv = directoryService->Get(NS_XPCOM_COMPONENT_REGISTRY_FILE,
|
||||
NS_GET_IID(nsIFile),
|
||||
getter_AddRefs(compregFile));
|
||||
rv = nsDirectoryService::gService->Get(NS_XPCOM_COMPONENT_REGISTRY_FILE,
|
||||
NS_GET_IID(nsIFile),
|
||||
getter_AddRefs(compregFile));
|
||||
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
|
@ -290,7 +282,6 @@ static PRBool CheckUpdateFile()
|
|||
|
||||
|
||||
nsComponentManagerImpl* nsComponentManagerImpl::gComponentManager = NULL;
|
||||
nsIProperties *gDirectoryService = NULL;
|
||||
PRBool gXPCOMShuttingDown = PR_FALSE;
|
||||
|
||||
// For each class that wishes to support nsIClassInfo, add a line like this
|
||||
|
@ -481,17 +472,7 @@ nsresult NS_COM NS_InitXPCOM2(nsIServiceManager* *result,
|
|||
|
||||
StartupSpecialSystemDirectory();
|
||||
|
||||
// Start the directory service so that the component manager init can use it.
|
||||
rv = nsDirectoryService::Create(nsnull,
|
||||
NS_GET_IID(nsIProperties),
|
||||
(void**)&gDirectoryService);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
nsCOMPtr<nsIDirectoryService> dirService = do_QueryInterface(gDirectoryService, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
rv = dirService->Init();
|
||||
rv = nsDirectoryService::RealInit();
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
|
@ -513,23 +494,23 @@ nsresult NS_COM NS_InitXPCOM2(nsIServiceManager* *result,
|
|||
rv = binDirectory->IsDirectory(&value);
|
||||
|
||||
if (NS_SUCCEEDED(rv) && value) {
|
||||
gDirectoryService->Set(NS_XPCOM_INIT_CURRENT_PROCESS_DIR, binDirectory);
|
||||
nsDirectoryService::gService->Set(NS_XPCOM_INIT_CURRENT_PROCESS_DIR, binDirectory);
|
||||
binDirectory->Clone(getter_AddRefs(xpcomLib));
|
||||
}
|
||||
}
|
||||
else {
|
||||
gDirectoryService->Get(NS_XPCOM_CURRENT_PROCESS_DIR,
|
||||
NS_GET_IID(nsIFile),
|
||||
getter_AddRefs(xpcomLib));
|
||||
nsDirectoryService::gService->Get(NS_XPCOM_CURRENT_PROCESS_DIR,
|
||||
NS_GET_IID(nsIFile),
|
||||
getter_AddRefs(xpcomLib));
|
||||
}
|
||||
|
||||
if (xpcomLib) {
|
||||
xpcomLib->AppendNative(nsDependentCString(XPCOM_DLL));
|
||||
gDirectoryService->Set(NS_XPCOM_LIBRARY_FILE, xpcomLib);
|
||||
nsDirectoryService::gService->Set(NS_XPCOM_LIBRARY_FILE, xpcomLib);
|
||||
}
|
||||
|
||||
if (appFileLocationProvider) {
|
||||
rv = dirService->RegisterProvider(appFileLocationProvider);
|
||||
rv = nsDirectoryService::gService->RegisterProvider(appFileLocationProvider);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
|
||||
|
@ -621,9 +602,9 @@ nsresult NS_COM NS_InitXPCOM2(nsIServiceManager* *result,
|
|||
#ifdef DEBUG_dougt
|
||||
printf("start - Registering GRE components\n");
|
||||
#endif
|
||||
rv = gDirectoryService->Get(NS_GRE_COMPONENT_DIR,
|
||||
NS_GET_IID(nsIFile),
|
||||
getter_AddRefs(greDir));
|
||||
rv = nsDirectoryService::gService->Get(NS_GRE_COMPONENT_DIR,
|
||||
NS_GET_IID(nsIFile),
|
||||
getter_AddRefs(greDir));
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_ERROR("Could not get GRE components directory!");
|
||||
return rv;
|
||||
|
@ -653,9 +634,9 @@ nsresult NS_COM NS_InitXPCOM2(nsIServiceManager* *result,
|
|||
//
|
||||
|
||||
nsCOMPtr<nsISimpleEnumerator> dirList;
|
||||
gDirectoryService->Get(NS_XPCOM_COMPONENT_DIR_LIST,
|
||||
NS_GET_IID(nsISimpleEnumerator),
|
||||
getter_AddRefs(dirList));
|
||||
nsDirectoryService::gService->Get(NS_XPCOM_COMPONENT_DIR_LIST,
|
||||
NS_GET_IID(nsISimpleEnumerator),
|
||||
getter_AddRefs(dirList));
|
||||
if (dirList) {
|
||||
PRBool hasMore;
|
||||
while (NS_SUCCEEDED(dirList->HasMoreElements(&hasMore)) && hasMore) {
|
||||
|
@ -675,9 +656,9 @@ nsresult NS_COM NS_InitXPCOM2(nsIServiceManager* *result,
|
|||
|
||||
// Make sure the compreg file's mod time is current.
|
||||
nsCOMPtr<nsIFile> compregFile;
|
||||
rv = gDirectoryService->Get(NS_XPCOM_COMPONENT_REGISTRY_FILE,
|
||||
NS_GET_IID(nsIFile),
|
||||
getter_AddRefs(compregFile));
|
||||
rv = nsDirectoryService::gService->Get(NS_XPCOM_COMPONENT_REGISTRY_FILE,
|
||||
NS_GET_IID(nsIFile),
|
||||
getter_AddRefs(compregFile));
|
||||
compregFile->SetLastModifiedTime(PR_Now() / 1000);
|
||||
}
|
||||
|
||||
|
@ -685,6 +666,11 @@ nsresult NS_COM NS_InitXPCOM2(nsIServiceManager* *result,
|
|||
nsIInterfaceInfoManager* iim = XPTI_GetInterfaceInfoManager();
|
||||
NS_IF_RELEASE(iim);
|
||||
|
||||
// After autoreg, but before we actually instantiate any components,
|
||||
// add any services listed in the "xpcom-directory-providers" category
|
||||
// to the directory service.
|
||||
nsDirectoryService::gService->RegisterCategoryProviders();
|
||||
|
||||
// Notify observers of xpcom autoregistration start
|
||||
NS_CreateServicesFromCategory(NS_XPCOM_STARTUP_OBSERVER_ID,
|
||||
nsnull,
|
||||
|
@ -813,7 +799,7 @@ nsresult NS_COM NS_ShutdownXPCOM(nsIServiceManager* servMgr)
|
|||
nsProxyObjectManager::Shutdown();
|
||||
|
||||
// Release the directory service
|
||||
NS_IF_RELEASE(gDirectoryService);
|
||||
NS_IF_RELEASE(nsDirectoryService::gService);
|
||||
|
||||
// Shutdown nsLocalFile string conversion
|
||||
NS_ShutdownLocalFile();
|
||||
|
|
|
@ -101,12 +101,6 @@ interface nsIServiceManager : nsISupports
|
|||
*/
|
||||
#define NS_ERROR_SERVICE_IN_USE NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_XPCOM, 23)
|
||||
|
||||
// Observing xpcom startup. If you component has not been created, it will be.
|
||||
#define NS_XPCOM_STARTUP_OBSERVER_ID "xpcom-startup"
|
||||
|
||||
// Observing xpcom shutdown
|
||||
#define NS_XPCOM_SHUTDOWN_OBSERVER_ID "xpcom-shutdown"
|
||||
|
||||
// Observing xpcom autoregistration. Topics will be 'start' and 'stop'.
|
||||
#define NS_XPCOM_AUTOREGISTRATION_OBSERVER_ID "xpcom-autoregistration"
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsDirectoryService.h"
|
||||
#include "nsDirectoryServiceDefs.h"
|
||||
#include "nsLocalFile.h"
|
||||
|
@ -45,6 +46,10 @@
|
|||
#include "nsStaticAtom.h"
|
||||
#include "nsEnumeratorUtils.h"
|
||||
|
||||
#include "nsICategoryManager.h"
|
||||
#include "nsISimpleEnumerator.h"
|
||||
#include "nsIStringEnumerator.h"
|
||||
|
||||
#if defined(XP_MAC)
|
||||
#include <Folders.h>
|
||||
#include <Files.h>
|
||||
|
@ -120,7 +125,7 @@ nsDirectoryService::GetCurrentProcessDirectory(nsILocalFile** aFile)
|
|||
*aFile = nsnull;
|
||||
|
||||
// Set the component registry location:
|
||||
if (!mService)
|
||||
if (!gService)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsresult rv;
|
||||
|
@ -399,7 +404,7 @@ nsIAtom* nsDirectoryService::sSystemDirectory = nsnull;
|
|||
#endif
|
||||
|
||||
|
||||
nsDirectoryService* nsDirectoryService::mService = nsnull;
|
||||
nsDirectoryService* nsDirectoryService::gService = nsnull;
|
||||
|
||||
nsDirectoryService::nsDirectoryService() :
|
||||
mHashtable(256, PR_TRUE)
|
||||
|
@ -410,13 +415,14 @@ NS_METHOD
|
|||
nsDirectoryService::Create(nsISupports *outer, REFNSIID aIID, void **aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
if (!mService)
|
||||
NS_ENSURE_NO_AGGREGATION(outer);
|
||||
|
||||
if (!gService)
|
||||
{
|
||||
mService = new nsDirectoryService();
|
||||
if (!mService)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
return mService->QueryInterface(aIID, aResult);
|
||||
|
||||
return gService->QueryInterface(aIID, aResult);
|
||||
}
|
||||
|
||||
static const nsStaticAtom directory_atoms[] = {
|
||||
|
@ -503,13 +509,27 @@ static const nsStaticAtom directory_atoms[] = {
|
|||
#endif
|
||||
};
|
||||
|
||||
nsresult
|
||||
NS_IMETHODIMP
|
||||
nsDirectoryService::Init()
|
||||
{
|
||||
NS_NOTREACHED("Don't call me, I was for internal use only!");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDirectoryService::RealInit()
|
||||
{
|
||||
NS_ASSERTION(!gService, "Mustn't initialize twice!");
|
||||
|
||||
nsresult rv;
|
||||
|
||||
rv = NS_NewISupportsArray(getter_AddRefs(mProviders));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsRefPtr<nsDirectoryService> self = new nsDirectoryService();
|
||||
if (!self)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
rv = NS_NewISupportsArray(getter_AddRefs(self->mProviders));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
NS_RegisterStaticAtoms(directory_atoms, NS_ARRAY_LENGTH(directory_atoms));
|
||||
|
||||
|
@ -518,9 +538,12 @@ nsDirectoryService::Init()
|
|||
if (!defaultProvider)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
// AppendElement returns PR_TRUE for success.
|
||||
rv = mProviders->AppendElement(defaultProvider) ? NS_OK : NS_ERROR_FAILURE;
|
||||
rv = self->mProviders->AppendElement(defaultProvider) ? NS_OK : NS_ERROR_FAILURE;
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
return rv;
|
||||
self.swap(gService);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool
|
||||
|
@ -533,9 +556,6 @@ nsDirectoryService::ReleaseValues(nsHashKey* key, void* data, void* closure)
|
|||
|
||||
nsDirectoryService::~nsDirectoryService()
|
||||
{
|
||||
// clear the global
|
||||
mService = nsnull;
|
||||
|
||||
}
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS4(nsDirectoryService, nsIProperties, nsIDirectoryService, nsIDirectoryServiceProvider, nsIDirectoryServiceProvider2)
|
||||
|
@ -720,6 +740,38 @@ nsDirectoryService::RegisterProvider(nsIDirectoryServiceProvider *prov)
|
|||
return mProviders->AppendElement(supports) ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
void
|
||||
nsDirectoryService::RegisterCategoryProviders()
|
||||
{
|
||||
nsCOMPtr<nsICategoryManager> catman
|
||||
(do_GetService(NS_CATEGORYMANAGER_CONTRACTID));
|
||||
if (!catman)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsISimpleEnumerator> entries;
|
||||
catman->EnumerateCategory(XPCOM_DIRECTORY_PROVIDER_CATEGORY,
|
||||
getter_AddRefs(entries));
|
||||
|
||||
nsCOMPtr<nsIUTF8StringEnumerator> strings(do_QueryInterface(entries));
|
||||
if (!strings)
|
||||
return;
|
||||
|
||||
PRBool more;
|
||||
while (NS_SUCCEEDED(strings->HasMore(&more)) && more) {
|
||||
nsCAutoString entry;
|
||||
strings->GetNext(entry);
|
||||
|
||||
nsXPIDLCString contractID;
|
||||
catman->GetCategoryEntry(XPCOM_DIRECTORY_PROVIDER_CATEGORY, entry.get(), getter_Copies(contractID));
|
||||
|
||||
if (contractID) {
|
||||
nsCOMPtr<nsIDirectoryServiceProvider> provider = do_GetService(contractID.get());
|
||||
if (provider)
|
||||
RegisterProvider(provider);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDirectoryService::UnregisterProvider(nsIDirectoryServiceProvider *prov)
|
||||
{
|
||||
|
|
|
@ -67,16 +67,19 @@ class nsDirectoryService : public nsIDirectoryService,
|
|||
NS_DECL_NSIDIRECTORYSERVICEPROVIDER2
|
||||
|
||||
nsDirectoryService();
|
||||
~nsDirectoryService();
|
||||
|
||||
static nsresult RealInit();
|
||||
void RegisterCategoryProviders();
|
||||
|
||||
static NS_METHOD
|
||||
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
|
||||
|
||||
private:
|
||||
~nsDirectoryService();
|
||||
static nsDirectoryService* gService;
|
||||
|
||||
private:
|
||||
nsresult GetCurrentProcessDirectory(nsILocalFile** aFile);
|
||||
|
||||
static nsDirectoryService* mService;
|
||||
static PRBool PR_CALLBACK ReleaseValues(nsHashKey* key, void* data, void* closure);
|
||||
nsSupportsHashtable mHashtable;
|
||||
nsCOMPtr<nsISupportsArray> mProviders;
|
||||
|
|
Загрузка…
Ссылка в новой задаче