diff --git a/xpcom/build/nsXPCOMPrivate.h b/xpcom/build/nsXPCOMPrivate.h index 38720a2df65b..de94950ad7b3 100644 --- a/xpcom/build/nsXPCOMPrivate.h +++ b/xpcom/build/nsXPCOMPrivate.h @@ -270,6 +270,7 @@ void LogTerm(); #endif extern bool gXPCOMShuttingDown; +extern bool gXPCOMThreadsShutDown; namespace mozilla { namespace services { diff --git a/xpcom/build/nsXPComInit.cpp b/xpcom/build/nsXPComInit.cpp index 591a96363689..0fc6044dd105 100644 --- a/xpcom/build/nsXPComInit.cpp +++ b/xpcom/build/nsXPComInit.cpp @@ -240,6 +240,7 @@ nsXPTIInterfaceInfoManagerGetSingleton(nsISupports* outer, nsComponentManagerImpl* nsComponentManagerImpl::gComponentManager = NULL; bool gXPCOMShuttingDown = false; +bool gXPCOMThreadsShutDown = false; static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID); static NS_DEFINE_CID(kINIParserFactoryCID, NS_INIPARSERFACTORY_CID); @@ -587,6 +588,7 @@ ShutdownXPCOM(nsIServiceManager* servMgr) NotifyObservers(nullptr, NS_XPCOM_SHUTDOWN_THREADS_OBSERVER_ID, nullptr); + gXPCOMThreadsShutDown = true; nsCycleCollector_shutdownThreads(); NS_ProcessPendingEvents(thread); diff --git a/xpcom/threads/Makefile.in b/xpcom/threads/Makefile.in index 2de09e5aad7c..b57c3cb361e5 100644 --- a/xpcom/threads/Makefile.in +++ b/xpcom/threads/Makefile.in @@ -15,6 +15,7 @@ MOZILLA_INTERNAL_API = 1 LIBXUL_LIBRARY = 1 LOCAL_INCLUDES = -I$(srcdir)/../components +LOCAL_INCLUDES = -I$(srcdir)/../build # we don't want the shared lib, but we want to force the creation of a static lib. FORCE_STATIC_LIB = 1 diff --git a/xpcom/threads/nsThread.cpp b/xpcom/threads/nsThread.cpp index 75ce11cf5e69..6517dd7060d4 100644 --- a/xpcom/threads/nsThread.cpp +++ b/xpcom/threads/nsThread.cpp @@ -15,6 +15,7 @@ #include "nsIObserverService.h" #include "mozilla/HangMonitor.h" #include "mozilla/Services.h" +#include "nsXPCOMPrivate.h" #define HAVE_UALARM _BSD_SOURCE || (_XOPEN_SOURCE >= 500 || \ _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED) && \ @@ -388,6 +389,10 @@ nsThread::Dispatch(nsIRunnable *event, uint32_t flags) NS_ENSURE_ARG_POINTER(event); + if (gXPCOMThreadsShutDown && MAIN_THREAD != mIsMainThread) { + return NS_ERROR_ILLEGAL_DURING_SHUTDOWN; + } + if (flags & DISPATCH_SYNC) { nsThread *thread = nsThreadManager::get()->GetCurrentThread(); NS_ENSURE_STATE(thread);