7272
7373#include " nsEventQueueService.h"
7474#include " nsEventQueue.h"
75+ #include " nsEventQueueUtils.h"
7576
7677#include " nsIProxyObjectManager.h"
7778#include " nsProxyEventPrivate.h" // access to the impl of nsProxyObjectManager for the generic factory registration.
@@ -142,7 +143,6 @@ extern void _FreeAutoLockStatics();
142143
143144static NS_DEFINE_CID (kComponentManagerCID , NS_COMPONENTMANAGER_CID);
144145static NS_DEFINE_CID (kMemoryCID , NS_MEMORY_CID);
145- static NS_DEFINE_CID (kEventQueueServiceCID , NS_EVENTQUEUESERVICE_CID);
146146static NS_DEFINE_CID (kINIParserFactoryCID , NS_INIPARSERFACTORY_CID);
147147
148148NS_GENERIC_FACTORY_CONSTRUCTOR (nsProcess)
@@ -773,11 +773,15 @@ NS_UnregisterXPCOMExitRoutine(XPCOMExitRoutine exitRoutine)
773773//
774774// The shutdown sequence for xpcom would be
775775//
776+ // - Notify "xpcom-shutdown" for modules to release primary (root) references
777+ // - Notify "xpcom-shutdown-threads" for thread joins
778+ // - Shutdown the main event queue (TODO)
776779// - Release the Global Service Manager
777780// - Release all service instances held by the global service manager
778781// - Release the Global Service Manager itself
779782// - Release the Component Manager
780783// - Release all factories cached by the Component Manager
784+ // - Notify module loaders to shut down
781785// - Unload Libraries
782786// - Release Contractid Cache held by Component Manager
783787// - Release dll abstraction held by Component Manager
@@ -787,37 +791,52 @@ NS_UnregisterXPCOMExitRoutine(XPCOMExitRoutine exitRoutine)
787791EXPORT_XPCOM_API (nsresult)
788792NS_ShutdownXPCOM (nsIServiceManager* servMgr)
789793{
794+ nsresult rv;
795+
796+ // grab the event queue so that we can process events before exiting.
797+ nsCOMPtr <nsIEventQueue> currentQ;
798+ NS_GetCurrentEventQ (getter_AddRefs(currentQ));
799+
800+ nsCOMPtr<nsISimpleEnumerator> moduleLoaders;
790801
791802 // Notify observers of xpcom shutting down
792- nsresult rv = NS_OK;
793803 {
794804 // Block it so that the COMPtr will get deleted before we hit
795805 // servicemanager shutdown
796806 nsCOMPtr<nsIObserverService> observerService =
797- do_GetService (" @mozilla.org/observer-service;1" , &rv);
798- if (NS_SUCCEEDED(rv))
807+ do_GetService (" @mozilla.org/observer-service;1" );
808+
809+ if (observerService)
799810 {
800811 nsCOMPtr<nsIServiceManager> mgr;
801812 rv = NS_GetServiceManager(getter_AddRefs (mgr));
802813 if (NS_SUCCEEDED(rv))
803814 {
804- (void ) observerService->NotifyObservers (mgr,
805- NS_XPCOM_SHUTDOWN_OBSERVER_ID,
806- nsnull);
815+ (void ) observerService->
816+ NotifyObservers (mgr, NS_XPCOM_SHUTDOWN_OBSERVER_ID,
817+ nsnull);
807818 }
808819 }
809- }
810820
811- // grab the event queue so that we can process events one last time before exiting
812- nsCOMPtr <nsIEventQueue> currentQ;
813- {
814- nsCOMPtr<nsIEventQueueService> eventQService =
815- do_GetService (kEventQueueServiceCID , &rv);
821+ if (currentQ)
822+ currentQ->ProcessPendingEvents ();
816823
817- if (eventQService) {
818- eventQService->GetThreadEventQueue (NS_CURRENT_THREAD, getter_AddRefs (currentQ));
819- }
824+ if (observerService)
825+ (void ) observerService->
826+ NotifyObservers (nsnull, NS_XPCOM_SHUTDOWN_THREADS_OBSERVER_ID,
827+ nsnull);
828+
829+ if (currentQ)
830+ currentQ->ProcessPendingEvents ();
831+
832+ // We save the "xpcom-shutdown-loaders" observers to notify after
833+ // the observerservice is gone.
834+ if (observerService)
835+ observerService->
836+ EnumerateObservers (NS_XPCOM_SHUTDOWN_LOADERS_OBSERVER_ID,
837+ getter_AddRefs (moduleLoaders));
820838 }
839+
821840 // XPCOM is officially in shutdown mode NOW
822841 // Set this only after the observers have been notified as this
823842 // will cause servicemanager to become inaccessible.
@@ -845,6 +864,27 @@ NS_ShutdownXPCOM(nsIServiceManager* servMgr)
845864 // Release the directory service
846865 NS_IF_RELEASE (nsDirectoryService::gService );
847866
867+ if (moduleLoaders) {
868+ PRBool more;
869+ nsCOMPtr<nsISupports> el;
870+ while (NS_SUCCEEDED(moduleLoaders->HasMoreElements (&more)) &&
871+ more) {
872+ moduleLoaders->GetNext (getter_AddRefs (el));
873+
874+ // Don't worry about weak-reference observers here: there is
875+ // no reason for weak-ref observers to register for
876+ // xpcom-shutdown-loaders
877+
878+ nsCOMPtr<nsIObserver> obs (do_QueryInterface (el));
879+ if (obs)
880+ (void ) obs->Observe (nsnull,
881+ NS_XPCOM_SHUTDOWN_LOADERS_OBSERVER_ID,
882+ nsnull);
883+ }
884+
885+ moduleLoaders = nsnull;
886+ }
887+
848888 // Shutdown nsLocalFile string conversion
849889 NS_ShutdownLocalFile ();
850890#ifdef XP_UNIX
0 commit comments