www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | Submodules | README | LICENSE

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:
Mchrome/content/zotero/xpcom/db.js | 11+++++++++--
Mchrome/content/zotero/xpcom/ipc.js | 7+++++--
Mchrome/content/zotero/xpcom/zotero.js | 9+++++++--
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"); });