Bug 529821 - Places should shutdown earlier (at profile-before-change). r=sdwilsh r=ehsan

This commit is contained in:
Marco Bonardo 2010-04-22 14:53:54 +02:00
parent 371a807e0e
commit 8cb61d80c1
26 changed files with 182 additions and 185 deletions

View File

@ -108,6 +108,7 @@ BrowserGlue.prototype = {
_isIdleObserver: false,
_isPlacesInitObserver: false,
_isPlacesLockedObserver: false,
_isPlacesShutdownObserver: false,
_isPlacesDatabaseLocked: false,
_setPrefToSaveSession: function BG__setPrefToSaveSession(aForce) {
@ -149,7 +150,6 @@ BrowserGlue.prototype = {
// This pref must be set here because SessionStore will use its value
// on quit-application.
this._setPrefToSaveSession();
this._onProfileShutdown();
break;
#ifdef OBSERVE_LASTWINDOW_CLOSE_TOPICS
case "browser-lastwindow-close-requested":
@ -185,6 +185,15 @@ BrowserGlue.prototype = {
Services.obs.removeObserver(this, "places-database-locked");
this._isPlacesLockedObserver = false;
break;
case "places-shutdown":
if (this._isPlacesShutdownObserver) {
Services.obs.removeObserver(this, "places-shutdown");
this._isPlacesShutdownObserver = false;
}
// places-shutdown is fired on profile-before-change, but before
// Places executes the last flush and closes connection.
this._onProfileShutdown();
break;
case "idle":
if (this._idleService.idleTime > BOOKMARKS_BACKUP_IDLE_TIME * 1000)
this._backupBookmarks();
@ -213,47 +222,51 @@ BrowserGlue.prototype = {
// initialization (called on application startup)
_init: function BG__init() {
// observer registration
Services.obs.addObserver(this, "xpcom-shutdown", false);
Services.obs.addObserver(this, "prefservice:after-app-defaults", false);
Services.obs.addObserver(this, "final-ui-startup", false);
Services.obs.addObserver(this, "sessionstore-windows-restored", false);
Services.obs.addObserver(this, "browser:purge-session-history", false);
Services.obs.addObserver(this, "quit-application-requested", false);
Services.obs.addObserver(this, "quit-application-granted", false);
let addObserver = Services.obs.addObserver;
addObserver(this, "xpcom-shutdown", false);
addObserver(this, "prefservice:after-app-defaults", false);
addObserver(this, "final-ui-startup", false);
addObserver(this, "sessionstore-windows-restored", false);
addObserver(this, "browser:purge-session-history", false);
addObserver(this, "quit-application-requested", false);
addObserver(this, "quit-application-granted", false);
#ifdef OBSERVE_LASTWINDOW_CLOSE_TOPICS
Services.obs.addObserver(this, "browser-lastwindow-close-requested", false);
Services.obs.addObserver(this, "browser-lastwindow-close-granted", false);
addObserver(this, "browser-lastwindow-close-requested", false);
addObserver(this, "browser-lastwindow-close-granted", false);
#endif
Services.obs.addObserver(this, "session-save", false);
Services.obs.addObserver(this, "places-init-complete", false);
addObserver(this, "session-save", false);
addObserver(this, "places-init-complete", false);
this._isPlacesInitObserver = true;
Services.obs.addObserver(this, "places-database-locked", false);
addObserver(this, "places-database-locked", false);
this._isPlacesLockedObserver = true;
Services.obs.addObserver(this, "distribution-customization-complete", false);
addObserver(this, "distribution-customization-complete", false);
addObserver(this, "places-shutdown", false);
this._isPlacesShutdownObserver = true;
},
// cleanup (called on application shutdown)
_dispose: function BG__dispose() {
// observer removal
Services.obs.removeObserver(this, "xpcom-shutdown");
Services.obs.removeObserver(this, "prefservice:after-app-defaults");
Services.obs.removeObserver(this, "final-ui-startup");
Services.obs.removeObserver(this, "sessionstore-windows-restored");
Services.obs.removeObserver(this, "browser:purge-session-history");
Services.obs.removeObserver(this, "quit-application-requested");
Services.obs.removeObserver(this, "quit-application-granted");
let removeObserver = Services.obs.removeObserver;
removeObserver(this, "xpcom-shutdown");
removeObserver(this, "prefservice:after-app-defaults");
removeObserver(this, "final-ui-startup");
removeObserver(this, "sessionstore-windows-restored");
removeObserver(this, "browser:purge-session-history");
removeObserver(this, "quit-application-requested");
removeObserver(this, "quit-application-granted");
#ifdef OBSERVE_LASTWINDOW_CLOSE_TOPICS
Services.obs.removeObserver(this, "browser-lastwindow-close-requested");
Services.obs.removeObserver(this, "browser-lastwindow-close-granted");
removeObserver(this, "browser-lastwindow-close-requested");
removeObserver(this, "browser-lastwindow-close-granted");
#endif
Services.obs.removeObserver(this, "session-save");
removeObserver(this, "session-save");
if (this._isIdleObserver)
this._idleService.removeIdleObserver(this, BOOKMARKS_BACKUP_IDLE_TIME);
if (this._isPlacesInitObserver)
Services.obs.removeObserver(this, "places-init-complete");
removeObserver(this, "places-init-complete");
if (this._isPlacesLockedObserver)
Services.obs.removeObserver(this, "places-database-locked");
removeObserver(this, "places-database-locked");
if (this._isPlacesShutdownObserver)
removeObserver(this, "places-shutdown");
},
_onAppDefaults: function BG__onAppDefaults() {
@ -309,8 +322,6 @@ BrowserGlue.prototype = {
} catch (e) { }
#endif
this._shutdownPlaces();
this._idleService.removeIdleObserver(this, BOOKMARKS_BACKUP_IDLE_TIME);
this._isIdleObserver = false;
this._sanitizer.onShutdown();
},
@ -859,6 +870,10 @@ BrowserGlue.prototype = {
* so replace this method with a no-op when first called.
*/
_shutdownPlaces: function BG__shutdownPlaces() {
if (this._isIdleObserver) {
this._idleService.removeIdleObserver(this, BOOKMARKS_BACKUP_IDLE_TIME);
this._isIdleObserver = false;
}
this._backupBookmarks();
// Backup bookmarks to bookmarks.html to support apps that depend

View File

@ -66,7 +66,7 @@ XPCOMUtils.defineLazyGetter(this, "PlacesUtils", function() {
const MIN_TRANSACTIONS_FOR_BATCH = 5;
function placesTransactionsService() {
Services.obs.addObserver(this, "xpcom-shutdown", false);
Services.obs.addObserver(this, PlacesUtils.TOPIC_SHUTDOWN, false);
this.mTransactionManager = Cc["@mozilla.org/transactionmanager;1"].
createInstance(Ci.nsITransactionManager);
}
@ -84,8 +84,8 @@ placesTransactionsService.prototype = {
// nsIObserver
observe: function PlacesTxn_observe(aSubject, aTopic, aData) {
if (aTopic == "xpcom-shutdown") {
Services.obs.removeObserver(this, "xpcom-shutdown");
if (aTopic == PlacesUtils.TOPIC_SHUTDOWN) {
Services.obs.removeObserver(this, PlacesUtils.TOPIC_SHUTDOWN);
delete this.mTransactionManager;
}
},

View File

@ -96,7 +96,7 @@ function run_test() {
getService(Ci.nsIObserverService);
let observer = {
observe: function(aSubject, aTopic, aData) {
os.removeObserver(this, TOPIC_PLACES_INIT_COMPLETE);
os.removeObserver(this, PlacesUtils.TOPIC_INIT_COMPLETE);
// Simulate browser startup.
bg.QueryInterface(Ci.nsIObserver).observe(null,
@ -112,7 +112,7 @@ function run_test() {
os.addObserver(cObserver, TOPIC_CUSTOMIZATION_COMPLETE, false);
}
}
os.addObserver(observer, TOPIC_PLACES_INIT_COMPLETE, false);
os.addObserver(observer, PlacesUtils.TOPIC_INIT_COMPLETE, false);
}
function continue_test() {

View File

@ -79,7 +79,7 @@ tests.push({
// Force nsBrowserGlue::_initPlaces().
print("Simulate Places init");
bg.QueryInterface(Ci.nsIObserver).observe(null,
TOPIC_PLACES_INIT_COMPLETE,
PlacesUtils.TOPIC_INIT_COMPLETE,
null);
// Check bookmarks.html has been imported, and a smart bookmark has been
// created.
@ -108,7 +108,7 @@ tests.push({
// Force nsBrowserGlue::_initPlaces().
print("Simulate Places init");
bg.QueryInterface(Ci.nsIObserver).observe(null,
TOPIC_PLACES_INIT_COMPLETE,
PlacesUtils.TOPIC_INIT_COMPLETE,
null);
// Check bookmarks.html has been imported, but smart bookmarks have not
// been created.
@ -136,7 +136,7 @@ tests.push({
// Force nsBrowserGlue::_initPlaces()
print("Simulate Places init");
bg.QueryInterface(Ci.nsIObserver).observe(null,
TOPIC_PLACES_INIT_COMPLETE,
PlacesUtils.TOPIC_INIT_COMPLETE,
null);
// Check bookmarks.html has been imported, but smart bookmarks have not
// been created.
@ -165,7 +165,7 @@ tests.push({
// Force nsBrowserGlue::_initPlaces()
print("Simulate Places init");
bg.QueryInterface(Ci.nsIObserver).observe(null,
TOPIC_PLACES_INIT_COMPLETE,
PlacesUtils.TOPIC_INIT_COMPLETE,
null);
// Check bookmarks.html has been imported, but smart bookmarks have not
// been created.
@ -191,7 +191,7 @@ tests.push({
// Force nsBrowserGlue::_initPlaces()
print("Simulate Places init");
bg.QueryInterface(Ci.nsIObserver).observe(null,
TOPIC_PLACES_INIT_COMPLETE,
PlacesUtils.TOPIC_INIT_COMPLETE,
null);
// Check bookmarks.html has been restored.
let itemId = bs.getIdForItemAt(bs.toolbarFolder, SMART_BOOKMARKS_ON_TOOLBAR + 1);
@ -217,7 +217,7 @@ tests.push({
// Force nsBrowserGlue::_initPlaces()
print("Simulate Places init");
bg.QueryInterface(Ci.nsIObserver).observe(null,
TOPIC_PLACES_INIT_COMPLETE,
PlacesUtils.TOPIC_INIT_COMPLETE,
null);
// Check bookmarks.html has been restored.
let itemId = bs.getIdForItemAt(bs.toolbarFolder, SMART_BOOKMARKS_ON_TOOLBAR + 1);
@ -247,9 +247,9 @@ function next_test() {
// nsBrowserGlue stops observing topics after first notification,
// so we add back the observer to test additional runs.
os.addObserver(bg.QueryInterface(Ci.nsIObserver),
TOPIC_PLACES_INIT_COMPLETE, false);
PlacesUtils.TOPIC_INIT_COMPLETE, false);
os.addObserver(bg.QueryInterface(Ci.nsIObserver),
TOPIC_PLACES_DATABASE_LOCKED, false);
PlacesUtils.TOPIC_DATABASE_LOCKED, false);
// Execute next test.
let test = tests.shift();
print("\nTEST " + (++testIndex) + ": " + test.description);

View File

@ -46,19 +46,14 @@ let bg = Cc["@mozilla.org/browser/browserglue;1"].
getService(Ci.nsIBrowserGlue);
// Initialize Places through Bookmarks Service.
let bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
getService(Ci.nsINavBookmarksService);
let bs = PlacesUtils.bookmarks;
// Get other services.
let ps = Cc["@mozilla.org/preferences-service;1"].
getService(Ci.nsIPrefBranch);
let os = Cc["@mozilla.org/observer-service;1"].
getService(Ci.nsIObserverService);
let ps = Services.prefs;
let os = Services.obs;
const PREF_AUTO_EXPORT_HTML = "browser.bookmarks.autoExportHTML";
const TOPIC_QUIT_APPLICATION_GRANTED = "quit-application-granted";
let tests = [];
//------------------------------------------------------------------------------
@ -73,14 +68,9 @@ tests.push({
ps.setBoolPref(PREF_AUTO_EXPORT_HTML, true);
// Force nsBrowserGlue::_shutdownPlaces().
try {
bg.QueryInterface(Ci.nsIObserver).observe(null,
TOPIC_QUIT_APPLICATION_GRANTED,
null);
}
catch(ex) {
// This throws due to idle observer, we can ignore that.
}
bg.QueryInterface(Ci.nsIObserver).observe(null,
PlacesUtils.TOPIC_SHUTDOWN,
null);
// Check bookmarks.html has been created.
check_bookmarks_html();
@ -114,14 +104,9 @@ tests.push({
let fileSize = profileBookmarksHTMLFile.fileSize;
// Force nsBrowserGlue::_shutdownPlaces().
try {
bg.QueryInterface(Ci.nsIObserver).observe(null,
TOPIC_QUIT_APPLICATION_GRANTED,
null);
}
catch(ex) {
// This throws due to idle observer, we can ignore that.
}
bg.QueryInterface(Ci.nsIObserver).observe(null,
PlacesUtils.TOPIC_SHUTDOWN,
null);
// Check a new bookmarks.html has been created.
let profileBookmarksHTMLFile = check_bookmarks_html();
@ -153,14 +138,9 @@ tests.push({
let fileSize = profileBookmarksJSONFile.fileSize;
// Force nsBrowserGlue::_shutdownPlaces().
try {
bg.QueryInterface(Ci.nsIObserver).observe(null,
TOPIC_QUIT_APPLICATION_GRANTED,
null);
}
catch(ex) {
// This throws due to idle observer, we can ignore that.
}
bg.QueryInterface(Ci.nsIObserver).observe(null,
PlacesUtils.TOPIC_SHUTDOWN,
null);
// Check a new JSON backup has not been created.
do_check_true(profileBookmarksJSONFile.exists());

View File

@ -62,38 +62,28 @@ function uri(spec) {
newURI(spec, null, null);
}
// If there's no location registered for the profile direcotry, register one now.
var dirSvc = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties);
var profileDir = null;
try {
profileDir = dirSvc.get(NS_APP_USER_PROFILE_50_DIR, Ci.nsIFile);
} catch (e) {}
if (!profileDir) {
// Register our own provider for the profile directory.
// It will simply return the current directory.
var provider = {
getFile: function(prop, persistent) {
persistent.value = true;
if (prop == NS_APP_USER_PROFILE_50_DIR) {
return dirSvc.get("CurProcD", Ci.nsIFile);
}
if (prop == NS_APP_HISTORY_50_FILE) {
var histFile = dirSvc.get("CurProcD", Ci.nsIFile);
histFile.append("history.dat");
return histFile;
}
throw Cr.NS_ERROR_FAILURE;
},
QueryInterface: function(iid) {
if (iid.equals(Ci.nsIDirectoryServiceProvider) ||
iid.equals(Ci.nsISupports)) {
return this;
}
throw Cr.NS_ERROR_NO_INTERFACE;
var profileDir = do_get_profile();
var provider = {
getFile: function(prop, persistent) {
persistent.value = true;
if (prop == NS_APP_HISTORY_50_FILE) {
var histFile = profileDir.clone();
histFile.append("history.dat");
return histFile;
}
};
dirSvc.QueryInterface(Ci.nsIDirectoryService).registerProvider(provider);
}
throw Cr.NS_ERROR_FAILURE;
},
QueryInterface: function(iid) {
if (iid.equals(Ci.nsIDirectoryServiceProvider) ||
iid.equals(Ci.nsISupports)) {
return this;
}
throw Cr.NS_ERROR_NO_INTERFACE;
}
};
dirSvc.QueryInterface(Ci.nsIDirectoryService).registerProvider(provider);
// Do not attempt to restore any session since we don't have any windows
Cc["@mozilla.org/preferences-service;1"].

View File

@ -101,6 +101,8 @@ const MAX_REFRESH_TIME = 3600000;
// Minimum time between update checks, used to avoid flooding servers.
const MIN_REFRESH_TIME = 600000;
const TOPIC_SHUTDOWN = "places-shutdown";
function MarkLivemarkLoadFailed(aFolderId) {
// Bail out if this failed before.
if (ans.itemHasAnnotation(aFolderId, LMANNO_LOADFAILED))
@ -134,7 +136,7 @@ function LivemarkService() {
// Cleanup on shutdown.
this._obs = Cc[OS_CONTRACTID].getService(Ci.nsIObserverService);
this._obs.addObserver(this, "xpcom-shutdown", false);
this._obs.addObserver(this, TOPIC_SHUTDOWN, false);
// Observe bookmarks changes.
bms.addObserver(this, false);
@ -204,8 +206,8 @@ LivemarkService.prototype = {
// nsIObserver
observe: function LS_observe(aSubject, aTopic, aData) {
if (aTopic == "xpcom-shutdown") {
this._obs.removeObserver(this, "xpcom-shutdown");
if (aTopic == TOPIC_SHUTDOWN) {
this._obs.removeObserver(this, TOPIC_SHUTDOWN);
// Remove bookmarks observer.
bms.removeObserver(this);

View File

@ -78,6 +78,8 @@ const MIN_GENERATOR_NAME_LENGTH = 6;
const USER_MICROSUMMARY_GENS_DIR = "microsummary-generators";
const TOPIC_SHUTDOWN = "places-shutdown";
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyGetter(this, "NetUtil", function() {
@ -88,7 +90,7 @@ XPCOMUtils.defineLazyGetter(this, "NetUtil", function() {
Cu.import("resource://gre/modules/Services.jsm");
function MicrosummaryService() {
Services.obs.addObserver(this, "xpcom-shutdown", true);
Services.obs.addObserver(this, TOPIC_SHUTDOWN, true);
this._ans = Cc["@mozilla.org/browser/annotation-service;1"].
getService(Ci.nsIAnnotationService);
@ -142,7 +144,7 @@ MicrosummaryService.prototype = {
// nsIObserver
observe: function MSS_observe(subject, topic, data) {
switch (topic) {
case "xpcom-shutdown":
case TOPIC_SHUTDOWN:
this._destroy();
break;
case "nsPref:changed":
@ -173,7 +175,7 @@ MicrosummaryService.prototype = {
},
_destroy: function MSS__destroy() {
Services.obs.removeObserver(this, "xpcom-shutdown", true);
Services.obs.removeObserver(this, TOPIC_SHUTDOWN, true);
this._ans.removeObserver(this);
Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefService).
getBranch("browser.microsummary.").

View File

@ -197,17 +197,13 @@ static const PRInt64 USECS_PER_DAY = LL_INIT(20, 500654080);
// Max number of containers, used to initialize the params hash.
#define HISTORY_DATE_CONT_MAX 10
// Observed topics.
#ifdef MOZ_XUL
#define TOPIC_AUTOCOMPLETE_FEEDBACK_INCOMING "autocomplete-will-enter-text"
#define TOPIC_AUTOCOMPLETE_FEEDBACK_UPDATED "places-autocomplete-feedback-updated"
#endif
#define TOPIC_XPCOM_SHUTDOWN "xpcom-shutdown"
#define TOPIC_IDLE_DAILY "idle-daily"
#define TOPIC_DATABASE_VACUUM_STARTING "places-vacuum-starting"
#define TOPIC_DATABASE_LOCKED "places-database-locked"
#define TOPIC_PLACES_INIT_COMPLETE "places-init-complete"
#define TOPIC_PREF_CHANGED "nsPref:changed"
#define TOPIC_GLOBAL_SHUTDOWN "profile-before-change"
NS_IMPL_THREADSAFE_ADDREF(nsNavHistory)
NS_IMPL_THREADSAFE_RELEASE(nsNavHistory)
@ -486,7 +482,7 @@ nsNavHistory::Init()
nsCOMPtr<nsIObserverService> obsSvc =
do_GetService(NS_OBSERVERSERVICE_CONTRACTID);
if (obsSvc) {
(void)obsSvc->AddObserver(this, TOPIC_XPCOM_SHUTDOWN, PR_FALSE);
(void)obsSvc->AddObserver(this, TOPIC_GLOBAL_SHUTDOWN, PR_FALSE);
(void)obsSvc->AddObserver(this, TOPIC_IDLE_DAILY, PR_FALSE);
(void)obsSvc->AddObserver(this, NS_PRIVATE_BROWSING_SWITCH_TOPIC, PR_FALSE);
#ifdef MOZ_XUL
@ -5705,33 +5701,32 @@ nsNavHistory::Observe(nsISupports *aSubject, const char *aTopic,
{
NS_ASSERTION(NS_IsMainThread(), "This can only be called on the main thread");
if (strcmp(aTopic, TOPIC_XPCOM_SHUTDOWN) == 0) {
if (strcmp(aTopic, TOPIC_GLOBAL_SHUTDOWN) == 0) {
nsCOMPtr<nsIObserverService> os =
do_GetService(NS_OBSERVERSERVICE_CONTRACTID);
if (os) {
os->RemoveObserver(this, NS_PRIVATE_BROWSING_SWITCH_TOPIC);
os->RemoveObserver(this, TOPIC_IDLE_DAILY);
os->RemoveObserver(this, TOPIC_XPCOM_SHUTDOWN);
os->RemoveObserver(this, TOPIC_GLOBAL_SHUTDOWN);
#ifdef MOZ_XUL
os->RemoveObserver(this, TOPIC_AUTOCOMPLETE_FEEDBACK_INCOMING);
#endif
// Notify that Places is shutting down.
os->NotifyObservers(nsnull, TOPIC_PLACES_SHUTDOWN, nsnull);
}
// If xpcom-shutdown is called in the same scope as the service init, we
// should immediately serve the places-init topic, this way topic observers
// If shutdown happens in the same scope as the service init, we should
// immediately serve the places-init topic, this way topic observers
// won't try to access the database after xpcom-shutdown.
nsCOMPtr<nsISimpleEnumerator> e;
nsresult rv = os->EnumerateObservers(TOPIC_PLACES_INIT_COMPLETE,
getter_AddRefs(e));
if (NS_SUCCEEDED(rv) && e) {
// This covers a special case that can happen in tests, if the test
// does never interrupt the main thread we could receive xpcom-shutdown
// before we fire any notification, that means that if we notify now
// we will init the category cache after xpcom-shutdown, category
// observing services will be then initialized and leaked.
// We could shutdown earlier (see bug 529821) but also in such a case
// we could have async statements trying to notify after xpcom-shutdown,
// so, for now, we just avoid to notify from now on.
// does never interrupt the main thread we could shutdown
// before we fire any notification. That means that if we notify from now
// on, we could init the category cache after xpcom-shutdown and leak.
mCanNotify = false;
nsCOMPtr<nsIObserver> observer;
@ -5812,7 +5807,7 @@ nsNavHistory::Observe(nsISupports *aSubject, const char *aTopic,
}
else if (strcmp(aTopic, TOPIC_IDLE_DAILY) == 0) {
// Ensure our connection is still alive. The idle-daily observer is removed
// on xpcom-shutdown, but we could have closed the connection earlier due
// on shutdown, but we could have closed the connection earlier due
// to errors or during normal shutdown process.
NS_ENSURE_TRUE(mDBConn, NS_OK);
@ -6112,7 +6107,7 @@ nsNavHistory::CommitLazyMessages(PRBool aIsShutdown)
SetPageTitleInternal(message.uri, message.title);
break;
case LazyMessage::Type_Favicon: {
// Favicons cannot use async channels after xpcom-shutdown.
// Favicons cannot use async channels after shutdown.
if (aIsShutdown)
continue;
nsFaviconService* faviconService = nsFaviconService::GetFaviconService();

View File

@ -88,6 +88,19 @@
#define URI_LENGTH_MAX 65536
#define TITLE_LENGTH_MAX 4096
#ifdef MOZ_XUL
// Fired after autocomplete feedback has been updated.
#define TOPIC_AUTOCOMPLETE_FEEDBACK_UPDATED "places-autocomplete-feedback-updated"
#endif
// Fired when Places is shutting down.
#define TOPIC_PLACES_SHUTDOWN "places-shutdown"
// Fired when Places found a locked database while initing.
#define TOPIC_DATABASE_LOCKED "places-database-locked"
// Fired after Places inited.
#define TOPIC_PLACES_INIT_COMPLETE "places-init-complete"
// Fired before starting a VACUUM operation.
#define TOPIC_DATABASE_VACUUM_STARTING "places-vacuum-starting"
namespace mozilla {
namespace places {

View File

@ -72,7 +72,7 @@ const kBookTagSQLFragment =
book_tag_sql_fragment("tags", "GROUP_CONCAT(t.title, ',')", true);
// observer topics
const kXPComShutdown = "xpcom-shutdown";
const kTopicShutdown = "places-shutdown";
const kPrefChanged = "nsPref:changed";
// Match type constants. These indicate what type of search function we should
@ -378,7 +378,7 @@ function nsPlacesAutoComplete()
// register observers
this._os = Cc["@mozilla.org/observer-service;1"].
getService(Ci.nsIObserverService);
this._os.addObserver(this, kXPComShutdown, false);
this._os.addObserver(this, kTopicShutdown, false);
}
@ -521,8 +521,8 @@ nsPlacesAutoComplete.prototype = {
observe: function PAC_observe(aSubject, aTopic, aData)
{
if (aTopic == kXPComShutdown) {
this._os.removeObserver(this, kXPComShutdown);
if (aTopic == kTopicShutdown) {
this._os.removeObserver(this, kTopicShutdown);
// Remove our preference observer.
this._prefs.QueryInterface(Ci.nsIPrefBranch2).removeObserver("", this);

View File

@ -48,7 +48,7 @@ const Ci = Components.interfaces;
const Cr = Components.results;
const Cu = Components.utils;
const kXPComShutdown = "xpcom-shutdown";
const kTopicShutdown = "places-shutdown";
const kSyncFinished = "places-sync-finished";
const kDebugStopSync = "places-debug-stop-sync";
const kDebugStartSync = "places-debug-start-sync";
@ -84,7 +84,7 @@ function nsPlacesDBFlush()
// Register observers
this._os = Cc["@mozilla.org/observer-service;1"].
getService(Ci.nsIObserverService);
this._os.addObserver(this, kXPComShutdown, false);
this._os.addObserver(this, kTopicShutdown, false);
this._os.addObserver(this, kDebugStopSync, false);
this._os.addObserver(this, kDebugStartSync, false);
@ -118,8 +118,8 @@ nsPlacesDBFlush.prototype = {
observe: function DBFlush_observe(aSubject, aTopic, aData)
{
if (aTopic == kXPComShutdown) {
this._os.removeObserver(this, kXPComShutdown);
if (aTopic == kTopicShutdown) {
this._os.removeObserver(this, kTopicShutdown);
this._os.removeObserver(this, kDebugStopSync);
this._os.removeObserver(this, kDebugStartSync);
@ -134,7 +134,7 @@ nsPlacesDBFlush.prototype = {
// Other components could still make changes to history at this point,
// for example to clear private data on shutdown, so here we dispatch
// an event to the main thread so that we will sync after
// xpcom-shutdown ensuring all data have been saved.
// Places shutdown ensuring all data have been saved.
let tm = Cc["@mozilla.org/thread-manager;1"].
getService(Ci.nsIThreadManager);
tm.mainThread.dispatch({

View File

@ -80,7 +80,7 @@ const nsPlacesExpirationFactory = {
const MAX_INT64 = 9223372036854775807;
const TOPIC_XPCOM_SHUTDOWN = "xpcom-shutdown";
const TOPIC_SHUTDOWN = "places-shutdown";
const TOPIC_PREF_CHANGED = "nsPref:changed";
const TOPIC_DEBUG_START_EXPIRATION = "places-debug-start-expiration";
const TOPIC_EXPIRATION_FINISHED = "places-expiration-finished";
@ -468,7 +468,7 @@ function nsPlacesExpiration()
// Register topic observers.
this._os = Cc["@mozilla.org/observer-service;1"].
getService(Ci.nsIObserverService);
this._os.addObserver(this, TOPIC_XPCOM_SHUTDOWN, false);
this._os.addObserver(this, TOPIC_SHUTDOWN, false);
this._os.addObserver(this, TOPIC_DEBUG_START_EXPIRATION, false);
// Create our expiration timer.
@ -482,9 +482,9 @@ nsPlacesExpiration.prototype = {
observe: function PEX_observe(aSubject, aTopic, aData)
{
if (aTopic == TOPIC_XPCOM_SHUTDOWN) {
if (aTopic == TOPIC_SHUTDOWN) {
this._shuttingDown = true;
this._os.removeObserver(this, TOPIC_XPCOM_SHUTDOWN);
this._os.removeObserver(this, TOPIC_SHUTDOWN);
this._os.removeObserver(this, TOPIC_DEBUG_START_EXPIRATION);
this._prefBranch.removeObserver("", this);

View File

@ -45,6 +45,8 @@ const Cr = Components.results;
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
const TOPIC_SHUTDOWN = "places-shutdown";
/**
* The Places Tagging Service
*/
@ -57,7 +59,7 @@ function TaggingService() {
// Cleanup on shutdown.
this._obss = Cc["@mozilla.org/observer-service;1"].
getService(Ci.nsIObserverService);
this._obss.addObserver(this, "xpcom-shutdown", false);
this._obss.addObserver(this, TOPIC_SHUTDOWN, false);
XPCOMUtils.defineLazyServiceGetter(this, "_history",
"@mozilla.org/browser/nav-history-service;1",
@ -335,9 +337,9 @@ TaggingService.prototype = {
// nsIObserver
observe: function TS_observe(aSubject, aTopic, aData) {
if (aTopic == "xpcom-shutdown") {
if (aTopic == TOPIC_SHUTDOWN) {
this._bms.removeObserver(this);
this._obss.removeObserver(this, "xpcom-shutdown");
this._obss.removeObserver(this, TOPIC_SHUTDOWN);
}
},

View File

@ -114,6 +114,15 @@ var PlacesUtils = {
POST_DATA_ANNO: "bookmarkProperties/POSTData",
READ_ONLY_ANNO: "placesInternal/READ_ONLY",
TOPIC_SHUTDOWN: "places-shutdown",
TOPIC_INIT_COMPLETE: "places-init-complete",
TOPIC_DATABASE_LOCKED: "places-database-locked",
TOPIC_EXPIRATION_FINISHED: "places-expiration-finished",
TOPIC_FEEDBACK_UPDATED: "places-autocomplete-feedback-updated",
TOPIC_SYNC_FINISHED: "places-sync-finished",
TOPIC_FAVICONS_EXPIRED: "places-favicons-expired",
TOPIC_VACUUM_STARTING: "places-vacuum-starting",
asVisit: function(aNode) asVisit(aNode),
asFullVisit: function(aNode) asFullVisit(aNode),
asContainer: function(aNode) asContainer(aNode),
@ -237,7 +246,7 @@ var PlacesUtils = {
this.annotations.addObserver(this, false);
// observe shutdown, so we can remove the anno observer
Services.obs.addObserver(this, "xpcom-shutdown", false);
Services.obs.addObserver(this, this.TOPIC_SHUTDOWN, false);
var readOnly = this.annotations.getItemsWithAnnotation(this.READ_ONLY_ANNO);
this.__defineGetter__("_readOnly", function() readOnly);
@ -249,9 +258,9 @@ var PlacesUtils = {
// nsIObserver
observe: function PU_observe(aSubject, aTopic, aData) {
if (aTopic == "xpcom-shutdown") {
if (aTopic == this.TOPIC_SHUTDOWN) {
this.annotations.removeObserver(this);
Services.obs.removeObserver(this, "xpcom-shutdown");
Services.obs.removeObserver(this, this.TOPIC_SHUTDOWN);
}
},

View File

@ -56,9 +56,8 @@ let (commonFile = do_get_file("../head_common.js", false)) {
// Simulates an expiration at shutdown.
function shutdownExpiration()
{
const TOPIC_XPCOM_SHUTDOWN = "xpcom-shutdown";
let expire = Cc["@mozilla.org/places/expiration;1"].getService(Ci.nsIObserver);
expire.observe(null, TOPIC_XPCOM_SHUTDOWN, null);
expire.observe(null, PlacesUtils.TOPIC_SHUTDOWN, null);
}

View File

@ -110,7 +110,7 @@ function run_test() {
// Observe expirations.
observer = {
observe: function(aSubject, aTopic, aData) {
os.removeObserver(observer, TOPIC_EXPIRATION_FINISHED);
os.removeObserver(observer, PlacesUtils.TOPIC_EXPIRATION_FINISHED);
let pages = as.getPagesWithAnnotation("page_expire1");
do_check_eq(pages.length, 0);
@ -128,7 +128,7 @@ function run_test() {
do_test_finished();
}
};
os.addObserver(observer, TOPIC_EXPIRATION_FINISHED, false);
os.addObserver(observer, PlacesUtils.TOPIC_EXPIRATION_FINISHED, false);
// Expire all visits for the first 5 pages and the bookmarks.
force_expiration_step(10);

View File

@ -111,7 +111,7 @@ function run_test() {
// Observe expirations.
observer = {
observe: function(aSubject, aTopic, aData) {
os.removeObserver(observer, TOPIC_EXPIRATION_FINISHED);
os.removeObserver(observer, PlacesUtils.TOPIC_EXPIRATION_FINISHED);
let pages = as.getPagesWithAnnotation("page_expire1");
do_check_eq(pages.length, 0);
@ -129,7 +129,7 @@ function run_test() {
do_test_finished();
}
};
os.addObserver(observer, TOPIC_EXPIRATION_FINISHED, false);
os.addObserver(observer, PlacesUtils.TOPIC_EXPIRATION_FINISHED, false);
// Expire all visits for the first 5 pages and the bookmarks.
force_expiration_step(10);

View File

@ -175,7 +175,7 @@ function run_test() {
// Observe expirations.
observer = {
observe: function(aSubject, aTopic, aData) {
os.removeObserver(observer, TOPIC_EXPIRATION_FINISHED);
os.removeObserver(observer, PlacesUtils.TOPIC_EXPIRATION_FINISHED);
["expire_days", "expire_weeks", "expire_months"].forEach(function(aAnno) {
let pages = as.getPagesWithAnnotation(aAnno);
@ -202,7 +202,7 @@ function run_test() {
do_test_finished();
}
};
os.addObserver(observer, TOPIC_EXPIRATION_FINISHED, false);
os.addObserver(observer, PlacesUtils.TOPIC_EXPIRATION_FINISHED, false);
// Expire all visits for the bookmarks.
force_expiration_step(5);

View File

@ -87,7 +87,7 @@ function run_test() {
// Observe expirations.
observer = {
observe: function(aSubject, aTopic, aData) {
os.removeObserver(observer, TOPIC_EXPIRATION_FINISHED);
os.removeObserver(observer, PlacesUtils.TOPIC_EXPIRATION_FINISHED);
let pages = as.getPagesWithAnnotation("test1");
do_check_eq(pages.length, 0);
@ -101,7 +101,7 @@ function run_test() {
do_test_finished();
}
};
os.addObserver(observer, TOPIC_EXPIRATION_FINISHED, false);
os.addObserver(observer, PlacesUtils.TOPIC_EXPIRATION_FINISHED, false);
shutdownExpiration();
do_test_pending();

View File

@ -54,7 +54,7 @@ let gObserver = {
this.notifications++;
}
};
os.addObserver(gObserver, TOPIC_EXPIRATION_FINISHED, false);
os.addObserver(gObserver, PlacesUtils.TOPIC_EXPIRATION_FINISHED, false);
function run_test() {
// Set interval to a large value so we don't expire on it.
@ -67,7 +67,7 @@ function run_test() {
}
function check_result() {
os.removeObserver(gObserver, TOPIC_EXPIRATION_FINISHED);
os.removeObserver(gObserver, PlacesUtils.TOPIC_EXPIRATION_FINISHED);
do_check_eq(gObserver.notifications, 1);
do_test_finished();
}

View File

@ -136,14 +136,14 @@ function run_next_test() {
// Observe expirations.
observer = {
observe: function(aSubject, aTopic, aData) {
os.removeObserver(observer, TOPIC_EXPIRATION_FINISHED);
os.removeObserver(observer, PlacesUtils.TOPIC_EXPIRATION_FINISHED);
hs.removeObserver(historyObserver, false);
// This test finished.
check_result();
}
};
os.addObserver(observer, TOPIC_EXPIRATION_FINISHED, false);
os.addObserver(observer, PlacesUtils.TOPIC_EXPIRATION_FINISHED, false);
// Expire now, observers will check results.
force_expiration_step();

View File

@ -156,14 +156,14 @@ function run_next_test() {
// Observe expirations.
observer = {
observe: function(aSubject, aTopic, aData) {
os.removeObserver(observer, TOPIC_EXPIRATION_FINISHED);
os.removeObserver(observer, PlacesUtils.TOPIC_EXPIRATION_FINISHED);
hs.removeObserver(historyObserver, false);
// This test finished.
check_result();
}
};
os.addObserver(observer, TOPIC_EXPIRATION_FINISHED, false);
os.addObserver(observer, PlacesUtils.TOPIC_EXPIRATION_FINISHED, false);
// Expire now, observers will check results.
force_expiration_step(gCurrentTest.limitExpiration);

View File

@ -149,14 +149,14 @@ function run_next_test() {
// Observe expirations.
observer = {
observe: function(aSubject, aTopic, aData) {
os.removeObserver(observer, TOPIC_EXPIRATION_FINISHED);
os.removeObserver(observer, PlacesUtils.TOPIC_EXPIRATION_FINISHED);
hs.removeObserver(historyObserver, false);
// This test finished.
check_result();
}
};
os.addObserver(observer, TOPIC_EXPIRATION_FINISHED, false);
os.addObserver(observer, PlacesUtils.TOPIC_EXPIRATION_FINISHED, false);
setMaxPages(gCurrentTest.maxPages);
// Expire now, observers will check results.

View File

@ -158,7 +158,7 @@ function run_test() {
// Observe expirations.
observer = {
observe: function(aSubject, aTopic, aData) {
Services.obs.removeObserver(observer, TOPIC_EXPIRATION_FINISHED);
Services.obs.removeObserver(observer, PlacesUtils.TOPIC_EXPIRATION_FINISHED);
["expire_days", "expire_weeks", "expire_months", "expire_session",
"expire"].forEach(function(aAnno) {
@ -189,7 +189,7 @@ function run_test() {
do_test_finished();
}
};
Services.obs.addObserver(observer, TOPIC_EXPIRATION_FINISHED, false);
Services.obs.addObserver(observer, PlacesUtils.TOPIC_EXPIRATION_FINISHED, false);
// Expire all visits for the bookmarks.
hs.QueryInterface(Ci.nsIBrowserHistory).removeAllPages();

View File

@ -40,10 +40,8 @@ const NS_APP_PROFILE_DIR_STARTUP = "ProfDS";
const NS_APP_HISTORY_50_FILE = "UHist";
const NS_APP_BOOKMARKS_50_FILE = "BMarks";
const TOPIC_EXPIRATION_FINISHED = "places-expiration-finished";
const TOPIC_SHUTDOWN = "xpcom-shutdown";
const TOPIC_PLACES_INIT_COMPLETE = "places-init-complete";
const TOPIC_PLACES_DATABASE_LOCKED = "places-database-locked";
// Backwards compatible consts, use PlacesUtils properties if possible.
const TOPIC_GLOBAL_SHUTDOWN = "profile-before-change";
// Shortcuts to transactions type.
const TRANSITION_LINK = Ci.nsINavHistoryService.TRANSITION_LINK;
@ -341,11 +339,11 @@ function setPageTitle(aURI, aTitle) {
function waitForClearHistory(aCallback) {
let observer = {
observe: function(aSubject, aTopic, aData) {
Services.obs.removeObserver(this, TOPIC_EXPIRATION_FINISHED);
Services.obs.removeObserver(this, PlacesUtils.TOPIC_EXPIRATION_FINISHED);
aCallback();
}
};
Services.obs.addObserver(observer, TOPIC_EXPIRATION_FINISHED, false);
Services.obs.addObserver(observer, PlacesUtils.TOPIC_EXPIRATION_FINISHED, false);
PlacesUtils.bhistory.removeAllPages();
}
@ -358,15 +356,7 @@ function shutdownPlaces()
{
let hs = Cc["@mozilla.org/browser/nav-history-service;1"].
getService(Ci.nsIObserver);
hs.observe(null, TOPIC_SHUTDOWN, null);
let sync = Cc["@mozilla.org/places/sync;1"].
getService(Ci.nsIObserver);
sync.observe(null, TOPIC_SHUTDOWN, null);
let expire = Cc["@mozilla.org/places/expiration;1"].
getService(Ci.nsIObserver);
expire.observe(null, TOPIC_SHUTDOWN, null);
hs.observe(null, TOPIC_GLOBAL_SHUTDOWN, null);
}