Bug 463289 - nsNativeModuleLoader doesn't protect its internal data structures, and is accessed on multiple threads (symptom is RECURSION_LEVEL assertions in pldhash.c). This patch is the simple-but-slow path: proxy all non-main-thread requests to the main thread. This is probably sufficient because asking for modules is a relatively rare activity: the component manager caches the factory objects after a lookup, r=brendan

--HG--
extra : rebase_source : 3118096536b6271886d5c35a3486bb278dc0fd86
This commit is contained in:
Benjamin Smedberg 2008-11-26 14:39:36 -05:00
Родитель 15baaa2c9e
Коммит 7029b163e2
1 изменённых файлов: 23 добавлений и 0 удалений

Просмотреть файл

@ -60,10 +60,12 @@
#include "nsComponentManager.h"
#include "nsCRTGlue.h"
#include "nsModule.h"
#include "nsThreadUtils.h"
#include "nsTraceRefcntImpl.h"
#include "nsILocalFile.h"
#include "nsIModule.h"
#include "nsIProxyObjectManager.h"
#ifdef XP_WIN
#include <windows.h>
@ -98,6 +100,8 @@ NS_IMPL_RELEASE_USING_AGGREGATOR(nsNativeModuleLoader,
nsresult
nsNativeModuleLoader::Init()
{
NS_ASSERTION(NS_IsMainThread(), "Startup not on main thread?");
LOG(PR_LOG_DEBUG, ("nsNativeModuleLoader::Init()"));
return mLibraries.Init() ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
@ -108,6 +112,23 @@ nsNativeModuleLoader::LoadModule(nsILocalFile* aFile, nsIModule* *aResult)
{
nsresult rv;
if (!NS_IsMainThread()) {
// If this call is off the main thread, synchronously proxy it
// to the main thread.
nsCOMPtr<nsIModuleLoader> proxythis;
rv = NS_GetProxyForObject(NS_PROXY_TO_MAIN_THREAD,
NS_GET_IID(nsIModuleLoader),
this, NS_PROXY_SYNC,
getter_AddRefs(proxythis));
if (NS_FAILED(rv))
return rv;
return proxythis->LoadModule(aFile, aResult);
}
NS_ASSERTION(NS_IsMainThread(), "LoadModule should always proxy to the main thread!");
// Only load components that end in the proper dynamic library suffix
nsCAutoString filePath;
aFile->GetNativePath(filePath);
@ -255,6 +276,8 @@ nsNativeModuleLoader::UnloaderFunc(nsIHashable* aHashedFile,
void
nsNativeModuleLoader::UnloadLibraries()
{
NS_ASSERTION(NS_IsMainThread(), "Shutdown not on main thread?");
mLibraries.Enumerate(ReleaserFunc, nsnull);
mLibraries.Enumerate(UnloaderFunc, nsnull);
}