Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2011 Google Inc. All rights reserved. | 2 * Copyright (C) 2011 Google Inc. All rights reserved. |
| 3 * Copyright (C) 2013 Apple Inc. All rights reserved. | 3 * Copyright (C) 2013 Apple Inc. All rights reserved. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
| 7 * are met: | 7 * are met: |
| 8 * | 8 * |
| 9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
| 10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
| (...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 322 errorMessage = formatErrorMessage("unable to open database", m_sqliteDat abase.lastError(), m_sqliteDatabase.lastErrorMsg()); | 322 errorMessage = formatErrorMessage("unable to open database", m_sqliteDat abase.lastError(), m_sqliteDatabase.lastErrorMsg()); |
| 323 return false; | 323 return false; |
| 324 } | 324 } |
| 325 if (!m_sqliteDatabase.turnOnIncrementalAutoVacuum()) | 325 if (!m_sqliteDatabase.turnOnIncrementalAutoVacuum()) |
| 326 WTF_LOG_ERROR("Unable to turn on incremental auto-vacuum (%d %s)", m_sql iteDatabase.lastError(), m_sqliteDatabase.lastErrorMsg()); | 326 WTF_LOG_ERROR("Unable to turn on incremental auto-vacuum (%d %s)", m_sql iteDatabase.lastError(), m_sqliteDatabase.lastErrorMsg()); |
| 327 | 327 |
| 328 m_sqliteDatabase.setBusyTimeout(maxSqliteBusyWaitTime); | 328 m_sqliteDatabase.setBusyTimeout(maxSqliteBusyWaitTime); |
| 329 | 329 |
| 330 String currentVersion; | 330 String currentVersion; |
| 331 { | 331 { |
| 332 MutexLocker locker(guidMutex()); | 332 GuidVersionMap::iterator entry; |
|
Vyacheslav Egorov (Google)
2014/06/13 12:49:39
An alternative less intrusive approach would be to
| |
| 333 | 333 GuidVersionMap::iterator end; |
| 334 GuidVersionMap::iterator entry = guidToVersionMap().find(m_guid); | 334 { |
| 335 if (entry != guidToVersionMap().end()) { | 335 MutexLocker locker(guidMutex()); |
| 336 entry = guidToVersionMap().find(m_guid); | |
| 337 end = guidToVersionMap().end(); | |
| 338 } | |
| 339 if (entry != end) { | |
| 336 // Map null string to empty string (see updateGuidVersionMap()). | 340 // Map null string to empty string (see updateGuidVersionMap()). |
| 337 currentVersion = entry->value.isNull() ? emptyString() : entry->valu e.isolatedCopy(); | 341 currentVersion = entry->value.isNull() ? emptyString() : entry->valu e.isolatedCopy(); |
| 338 WTF_LOG(StorageAPI, "Current cached version for guid %i is %s", m_gu id, currentVersion.ascii().data()); | 342 WTF_LOG(StorageAPI, "Current cached version for guid %i is %s", m_gu id, currentVersion.ascii().data()); |
| 339 | 343 |
| 340 // Note: In multi-process browsers the cached value may be inaccurat e, but | 344 // Note: In multi-process browsers the cached value may be inaccurat e, but |
| 341 // we cannot read the actual version from the database without poten tially | 345 // we cannot read the actual version from the database without poten tially |
| 342 // inducing a form of deadlock, a busytimeout error when trying to | 346 // inducing a form of deadlock, a busytimeout error when trying to |
| 343 // access the database. So we'll use the cached value if we're unabl e to read | 347 // access the database. So we'll use the cached value if we're unabl e to read |
| 344 // the value from the database file without waiting. | 348 // the value from the database file without waiting. |
| 345 // FIXME: Add an async openDatabase method to the DatabaseAPI. | 349 // FIXME: Add an async openDatabase method to the DatabaseAPI. |
| 346 const int noSqliteBusyWaitTime = 0; | 350 const int noSqliteBusyWaitTime = 0; |
| 347 m_sqliteDatabase.setBusyTimeout(noSqliteBusyWaitTime); | 351 m_sqliteDatabase.setBusyTimeout(noSqliteBusyWaitTime); |
| 348 String versionFromDatabase; | 352 String versionFromDatabase; |
| 349 if (getVersionFromDatabase(versionFromDatabase, false)) { | 353 if (getVersionFromDatabase(versionFromDatabase, false)) { |
| 350 currentVersion = versionFromDatabase; | 354 currentVersion = versionFromDatabase; |
| 355 MutexLocker locker(guidMutex()); | |
| 351 updateGuidVersionMap(m_guid, currentVersion); | 356 updateGuidVersionMap(m_guid, currentVersion); |
| 352 } | 357 } |
| 353 m_sqliteDatabase.setBusyTimeout(maxSqliteBusyWaitTime); | 358 m_sqliteDatabase.setBusyTimeout(maxSqliteBusyWaitTime); |
| 354 } else { | 359 } else { |
| 355 WTF_LOG(StorageAPI, "No cached version for guid %i", m_guid); | 360 WTF_LOG(StorageAPI, "No cached version for guid %i", m_guid); |
| 356 | 361 |
| 357 SQLiteTransaction transaction(m_sqliteDatabase); | 362 SQLiteTransaction transaction(m_sqliteDatabase); |
| 358 transaction.begin(); | 363 transaction.begin(); |
| 359 if (!transaction.inProgress()) { | 364 if (!transaction.inProgress()) { |
| 360 reportOpenDatabaseResult(2, InvalidStateError, m_sqliteDatabase. lastError()); | 365 reportOpenDatabaseResult(2, InvalidStateError, m_sqliteDatabase. lastError()); |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 388 WTF_LOG(StorageAPI, "Setting version %s in database %s that was just created", m_expectedVersion.ascii().data(), databaseDebugName().ascii().dat a()); | 393 WTF_LOG(StorageAPI, "Setting version %s in database %s that was just created", m_expectedVersion.ascii().data(), databaseDebugName().ascii().dat a()); |
| 389 if (!setVersionInDatabase(m_expectedVersion, false)) { | 394 if (!setVersionInDatabase(m_expectedVersion, false)) { |
| 390 reportOpenDatabaseResult(5, InvalidStateError, m_sqliteDatab ase.lastError()); | 395 reportOpenDatabaseResult(5, InvalidStateError, m_sqliteDatab ase.lastError()); |
| 391 errorMessage = formatErrorMessage("unable to open database, failed to write current version", m_sqliteDatabase.lastError(), m_sqliteDatabase .lastErrorMsg()); | 396 errorMessage = formatErrorMessage("unable to open database, failed to write current version", m_sqliteDatabase.lastError(), m_sqliteDatabase .lastErrorMsg()); |
| 392 transaction.rollback(); | 397 transaction.rollback(); |
| 393 m_sqliteDatabase.close(); | 398 m_sqliteDatabase.close(); |
| 394 return false; | 399 return false; |
| 395 } | 400 } |
| 396 currentVersion = m_expectedVersion; | 401 currentVersion = m_expectedVersion; |
| 397 } | 402 } |
| 398 updateGuidVersionMap(m_guid, currentVersion); | 403 |
| 399 transaction.commit(); | 404 { |
| 405 MutexLocker locker(guidMutex()); | |
| 406 entry = guidToVersionMap().find(m_guid); | |
| 407 end = guidToVersionMap().end(); | |
| 408 // We always update the map with the version when at this point. | |
| 409 updateGuidVersionMap(m_guid, currentVersion); | |
| 410 } | |
| 411 | |
| 412 // Only commit the transaction if no other thread has already create d the table, etc. | |
| 413 // We use the presence of an entry in the guidToVersionMap to determ ine if this thread | |
| 414 // is first. | |
| 415 if (entry != end) { | |
| 416 transaction.commit(); | |
| 417 } else { | |
| 418 // Some other thread has already created table, set the version, etc. | |
| 419 transaction.rollback(); | |
| 420 } | |
| 400 } | 421 } |
| 401 } | 422 } |
| 402 | 423 |
| 403 if (currentVersion.isNull()) { | 424 if (currentVersion.isNull()) { |
| 404 WTF_LOG(StorageAPI, "Database %s does not have its version set", databas eDebugName().ascii().data()); | 425 WTF_LOG(StorageAPI, "Database %s does not have its version set", databas eDebugName().ascii().data()); |
| 405 currentVersion = ""; | 426 currentVersion = ""; |
| 406 } | 427 } |
| 407 | 428 |
| 408 // If the expected version isn't the empty string, ensure that the current d atabase version we have matches that version. Otherwise, set an exception. | 429 // If the expected version isn't the empty string, ensure that the current d atabase version we have matches that version. Otherwise, set an exception. |
| 409 // If the expected version is the empty string, then we always return with w hatever version of the database we have. | 430 // If the expected version is the empty string, then we always return with w hatever version of the database we have. |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 666 { | 687 { |
| 667 executionContext()->addConsoleMessage(StorageMessageSource, ErrorMessageLeve l, message); | 688 executionContext()->addConsoleMessage(StorageMessageSource, ErrorMessageLeve l, message); |
| 668 } | 689 } |
| 669 | 690 |
| 670 ExecutionContext* DatabaseBackendBase::executionContext() const | 691 ExecutionContext* DatabaseBackendBase::executionContext() const |
| 671 { | 692 { |
| 672 return databaseContext()->executionContext(); | 693 return databaseContext()->executionContext(); |
| 673 } | 694 } |
| 674 | 695 |
| 675 } // namespace WebCore | 696 } // namespace WebCore |
| OLD | NEW |