commit d84bffb1c2fddfd409b7b090329595e894f0155b
parent 207c34b1a41e55f50662a0a6f3c83cffd022d35f
Author: Simon Kornblith <simon@simonster.com>
Date: Fri, 13 Dec 2013 17:19:56 -0500
Fixes that should hopefully protect against database corruption
- When opening the DB, always tell other Zotero instances to close it,
regardless of whether they are holding the lock.
- Don't let database re-open after it has been closed. This also fixes
some issues with connector switching.
Diffstat:
3 files changed, 21 insertions(+), 6 deletions(-)
diff --git a/chrome/content/zotero/xpcom/db.js b/chrome/content/zotero/xpcom/db.js
@@ -791,12 +791,17 @@ Zotero.DBConnection.prototype.checkException = function (e) {
}
-Zotero.DBConnection.prototype.closeDatabase = function () {
+/**
+ * Close the database
+ * @param {Boolean} [permanent] If true, throw an error instead of
+ * allowing code to re-open the database again
+ */
+Zotero.DBConnection.prototype.closeDatabase = function (permanent) {
if(this._connection) {
this.stopDummyStatement();
var deferred = Q.defer();
this._connection.asyncClose(deferred.resolve);
- this._connection = undefined;
+ this._connection = permanent ? false : null;
return deferred.promise;
} else {
return Q();
@@ -1073,6 +1078,8 @@ Zotero.DBConnection.prototype.getSQLDataType = function(value) {
Zotero.DBConnection.prototype._getDBConnection = function () {
if (this._connection) {
return this._connection;
+ } else if (this._connection === false) {
+ throw new Error("Database permanently closed; not re-opening");
}
this._debug("Opening database '" + this._dbName + "'");
diff --git a/chrome/content/zotero/xpcom/ipc.js b/chrome/content/zotero/xpcom/ipc.js
@@ -62,10 +62,13 @@ Zotero.IPC = new function() {
* has been received if it is already initialized, SA sends an initComplete message
* to Z4Fx.
*/
- if(msg === "releaseLock" && !Zotero.isConnector) {
+ if(msg.substr(0, 11) === "releaseLock") {
// Standalone sends this to the Firefox extension to tell the Firefox extension to
// release its lock on the Zotero database
- switchConnectorMode(true);
+ if(!Zotero.isConnector && (msg.length === 11 ||
+ msg.substr(12) === Zotero.getZoteroDirectory().persistentDescriptor)) {
+ switchConnectorMode(true);
+ }
} else if(msg === "lockReleased") {
// The Firefox extension sends this to Standalone to let Standalone know that it has
// released its lock
diff --git a/chrome/content/zotero/xpcom/zotero.js b/chrome/content/zotero/xpcom/zotero.js
@@ -759,6 +759,11 @@ Components.utils.import("resource://gre/modules/Services.jsm");
Zotero.DB.test();
var dbfile = Zotero.getZoteroDatabase();
+
+ // Tell any other Zotero instances to release their lock,
+ // in case we lost the lock on the database (how?) and it's
+ // now open in two places at once
+ Zotero.IPC.broadcast("releaseLock "+dbfile.persistentDescriptor);
// Test write access on Zotero data directory
if (!dbfile.parent.isWritable()) {
@@ -886,8 +891,8 @@ Components.utils.import("resource://gre/modules/Services.jsm");
// Zotero.DBConnection.getStatement() explicitly
Components.utils.forceGC();
- // unlock DB
- return Zotero.DB.closeDatabase().then(function() {
+ // close DB
+ return Zotero.DB.closeDatabase(true).then(function() {
// broadcast that DB lock has been released
Zotero.IPC.broadcast("lockReleased");
});