-
mark.lam@apple.com authored
https://bugs.webkit.org/show_bug.cgi?id=110600. Reviewed by Geoffrey Garen. Source/WebCore: 1. Introduced the OriginLock for synchronizing write access to the database origin directory. This allows us to more accurately compute the disk usage. The OriginLock uses a mutex to provide mutual exclusion between threads and a file lock for mutual exclusion between processes. The file lock part is conditional on USE(FILE_LOCK). The mutex mutual exclusion also serves to ensure that only 1 thread can write to a sqlite database at one time. 2. Change the SQLTransactionCoordinator to only allow one write transaction to an origin instead of one write transaction per database. This is needed in order to accurately compute the disk usage. It is also necessary so that the OriginLock does not deadlock itself (as would be the case if concurrent write transactions to different databases in the same origin are allowed). 3. Fix DatabaseTracker::getMaxSizeForDatabase() to check for when disk usage may exceed the quota, and ensure that we will return an appropriate max database size. Disk usage can exceed the usage if it is already near the quota limit but have not exceeded it yet. If a new database is opened in that origin, it may bump the usage above the quota, but should not continually repeat this. Subsequent attempts to open a database will find that the quota is already exhausted and fail. There is still a race condition pertaining to the tracker database getting out of sync that may still enable runaway growth in the database sizes. That issue only manifest in a multi-process environment, and will be fixed in another changeset. 4. Fixed a bug in SQLStatement to check if the errorCallback exists before invoking it. No new layout tests. A quota-test.html was attached to bugzilla for manual testing of multi-tab concurrent consumption of storage resource, and also to test handling situations when the user deletes the database files while the script is still using the database. * CMakeLists.txt: * GNUmakefile.list.am: * Modules/webdatabase/DatabaseTracker.cpp: (WebCore::DatabaseTracker::getMaxSizeForDatabase): (WebCore::DatabaseTracker::originLockFor): (WebCore::DatabaseTracker::deleteOriginLockFor): (WebCore::DatabaseTracker::deleteOrigin): * Modules/webdatabase/DatabaseTracker.h: * Modules/webdatabase/OriginLock.cpp: Added. (WebCore::OriginLock::lockFileNameForPath): (WebCore::OriginLock::OriginLock): (WebCore::OriginLock::~OriginLock): (WebCore::OriginLock::lock): (WebCore::OriginLock::unlock): * Modules/webdatabase/OriginLock.h: Added. * Modules/webdatabase/SQLStatement.cpp: (WebCore::SQLStatement::performCallback): * Modules/webdatabase/SQLTransactionBackend.cpp: (WebCore::SQLTransactionBackend::doCleanup): (WebCore::SQLTransactionBackend::computeNextStateAndCleanupIfNeeded): (WebCore::SQLTransactionBackend::openTransactionAndPreflight): (WebCore::SQLTransactionBackend::postflightAndCommit): (WebCore::SQLTransactionBackend::cleanupAfterTransactionErrorCallback): (WebCore::SQLTransactionBackend::acquireOriginLock): (WebCore::SQLTransactionBackend::releaseOriginLockIfNeeded): * Modules/webdatabase/SQLTransactionBackend.h: (SQLTransactionBackend): * Modules/webdatabase/SQLTransactionCoordinator.cpp: (WebCore::getDatabaseIdentifier): * Target.pri: * WebCore.gypi: * WebCore.vcproj/WebCore.vcproj: * WebCore.vcxproj/WebCore.vcxproj: * WebCore.vcxproj/WebCore.vcxproj.filters: * WebCore.xcodeproj/project.pbxproj: * config.h: * platform/FileSystem.h: * platform/posix/FileSystemPOSIX.cpp: (WebCore::lockFile): (WebCore::unlockFile): LayoutTests: * storage/websql/multiple-databases-garbage-collection.js: - This test runs 2 transactions on 2 databases (1 each). The 2 databases are named "persistent" and "forgotten". The test executes the transaction on "persistent" first, but expects the transaction on "forgotten" to finish first. This is because "forgotten"'s transaction is a smaller one. The new changes to SQLTransactionCoordinator now ensures that a write transaction must completes before another is started for databases in the same origin. Hence, the previously expected result will no longer be true. Regardless, the purpose of the test is not to test the order of completion but that resources are reclaimed. So, I'm changing the test to start the "forgotten" transaction first followed by the "persistent" transaction. This ensures that the test will yield consistent results even when run on ports that may allow more than one write transaction to run at the same time. git-svn-id: http://svn.webkit.org/repository/webkit/trunk@144760 268f45cc-cd09-0410-ab3c-d52691b4dbfc
f009ae4c