| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2007, 2008, 2013 Apple Inc. All rights reserved. | 2 * Copyright (C) 2007, 2008, 2013 Apple Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * | 7 * |
| 8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
| (...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 349 , m_wrapper(wrapper) | 349 , m_wrapper(wrapper) |
| 350 , m_hasCallback(m_frontend->hasCallback()) | 350 , m_hasCallback(m_frontend->hasCallback()) |
| 351 , m_hasSuccessCallback(m_frontend->hasSuccessCallback()) | 351 , m_hasSuccessCallback(m_frontend->hasSuccessCallback()) |
| 352 , m_hasErrorCallback(m_frontend->hasErrorCallback()) | 352 , m_hasErrorCallback(m_frontend->hasErrorCallback()) |
| 353 , m_shouldRetryCurrentStatement(false) | 353 , m_shouldRetryCurrentStatement(false) |
| 354 , m_modifiedDatabase(false) | 354 , m_modifiedDatabase(false) |
| 355 , m_lockAcquired(false) | 355 , m_lockAcquired(false) |
| 356 , m_readOnly(readOnly) | 356 , m_readOnly(readOnly) |
| 357 , m_hasVersionMismatch(false) | 357 , m_hasVersionMismatch(false) |
| 358 { | 358 { |
| 359 DCHECK(isMainThread()); |
| 359 ASSERT(m_database); | 360 ASSERT(m_database); |
| 360 m_frontend->setBackend(this); | 361 m_frontend->setBackend(this); |
| 361 m_requestedState = SQLTransactionState::AcquireLock; | 362 m_requestedState = SQLTransactionState::AcquireLock; |
| 362 } | 363 } |
| 363 | 364 |
| 364 SQLTransactionBackend::~SQLTransactionBackend() | 365 SQLTransactionBackend::~SQLTransactionBackend() |
| 365 { | 366 { |
| 366 ASSERT(!m_sqliteTransaction); | 367 ASSERT(!m_sqliteTransaction); |
| 367 } | 368 } |
| 368 | 369 |
| 369 DEFINE_TRACE(SQLTransactionBackend) | 370 DEFINE_TRACE(SQLTransactionBackend) |
| 370 { | 371 { |
| 371 visitor->trace(m_frontend); | |
| 372 visitor->trace(m_currentStatementBackend); | |
| 373 visitor->trace(m_database); | 372 visitor->trace(m_database); |
| 374 visitor->trace(m_wrapper); | 373 visitor->trace(m_wrapper); |
| 375 visitor->trace(m_statementQueue); | |
| 376 } | 374 } |
| 377 | 375 |
| 378 void SQLTransactionBackend::doCleanup() | 376 void SQLTransactionBackend::doCleanup() |
| 379 { | 377 { |
| 380 if (!m_frontend) | 378 if (!m_frontend) |
| 381 return; | 379 return; |
| 382 m_frontend = nullptr; // Break the reference cycle. See comment about the li
fe-cycle above. | 380 m_frontend = nullptr; // Break the reference cycle. See comment about the li
fe-cycle above. |
| 383 | 381 |
| 384 ASSERT(database()->getDatabaseContext()->databaseThread()->isDatabaseThread(
)); | 382 ASSERT(database()->getDatabaseContext()->databaseThread()->isDatabaseThread(
)); |
| 385 | 383 |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 460 }; | 458 }; |
| 461 | 459 |
| 462 ASSERT(WTF_ARRAY_LENGTH(stateFunctions) == static_cast<int>(SQLTransactionSt
ate::NumberOfStates)); | 460 ASSERT(WTF_ARRAY_LENGTH(stateFunctions) == static_cast<int>(SQLTransactionSt
ate::NumberOfStates)); |
| 463 ASSERT(state < SQLTransactionState::NumberOfStates); | 461 ASSERT(state < SQLTransactionState::NumberOfStates); |
| 464 | 462 |
| 465 return stateFunctions[static_cast<int>(state)]; | 463 return stateFunctions[static_cast<int>(state)]; |
| 466 } | 464 } |
| 467 | 465 |
| 468 void SQLTransactionBackend::enqueueStatementBackend(SQLStatementBackend* stateme
ntBackend) | 466 void SQLTransactionBackend::enqueueStatementBackend(SQLStatementBackend* stateme
ntBackend) |
| 469 { | 467 { |
| 468 DCHECK(isMainThread()); |
| 470 MutexLocker locker(m_statementMutex); | 469 MutexLocker locker(m_statementMutex); |
| 471 m_statementQueue.append(statementBackend); | 470 m_statementQueue.append(statementBackend); |
| 472 } | 471 } |
| 473 | 472 |
| 474 void SQLTransactionBackend::computeNextStateAndCleanupIfNeeded() | 473 void SQLTransactionBackend::computeNextStateAndCleanupIfNeeded() |
| 475 { | 474 { |
| 475 DCHECK(database()->getDatabaseContext()->databaseThread()->isDatabaseThread(
)); |
| 476 // Only honor the requested state transition if we're not supposed to be | 476 // Only honor the requested state transition if we're not supposed to be |
| 477 // cleaning up and shutting down: | 477 // cleaning up and shutting down: |
| 478 if (m_database->opened()) { | 478 if (m_database->opened()) { |
| 479 setStateToRequestedState(); | 479 setStateToRequestedState(); |
| 480 ASSERT(m_nextState == SQLTransactionState::AcquireLock | 480 ASSERT(m_nextState == SQLTransactionState::AcquireLock |
| 481 || m_nextState == SQLTransactionState::OpenTransactionAndPreflight | 481 || m_nextState == SQLTransactionState::OpenTransactionAndPreflight |
| 482 || m_nextState == SQLTransactionState::RunStatements | 482 || m_nextState == SQLTransactionState::RunStatements |
| 483 || m_nextState == SQLTransactionState::PostflightAndCommit | 483 || m_nextState == SQLTransactionState::PostflightAndCommit |
| 484 || m_nextState == SQLTransactionState::CleanupAndTerminate | 484 || m_nextState == SQLTransactionState::CleanupAndTerminate |
| 485 || m_nextState == SQLTransactionState::CleanupAfterTransactionErrorC
allback); | 485 || m_nextState == SQLTransactionState::CleanupAfterTransactionErrorC
allback); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 513 | 513 |
| 514 void SQLTransactionBackend::performNextStep() | 514 void SQLTransactionBackend::performNextStep() |
| 515 { | 515 { |
| 516 computeNextStateAndCleanupIfNeeded(); | 516 computeNextStateAndCleanupIfNeeded(); |
| 517 runStateMachine(); | 517 runStateMachine(); |
| 518 } | 518 } |
| 519 | 519 |
| 520 void SQLTransactionBackend::executeSQL(SQLStatement* statement, | 520 void SQLTransactionBackend::executeSQL(SQLStatement* statement, |
| 521 const String& sqlStatement, const Vector<SQLValue>& arguments, int permissio
ns) | 521 const String& sqlStatement, const Vector<SQLValue>& arguments, int permissio
ns) |
| 522 { | 522 { |
| 523 DCHECK(isMainThread()); |
| 523 enqueueStatementBackend(SQLStatementBackend::create(statement, sqlStatement,
arguments, permissions)); | 524 enqueueStatementBackend(SQLStatementBackend::create(statement, sqlStatement,
arguments, permissions)); |
| 524 } | 525 } |
| 525 | 526 |
| 526 void SQLTransactionBackend::notifyDatabaseThreadIsShuttingDown() | 527 void SQLTransactionBackend::notifyDatabaseThreadIsShuttingDown() |
| 527 { | 528 { |
| 528 ASSERT(database()->getDatabaseContext()->databaseThread()->isDatabaseThread(
)); | 529 ASSERT(database()->getDatabaseContext()->databaseThread()->isDatabaseThread(
)); |
| 529 | 530 |
| 530 // If the transaction is in progress, we should roll it back here, since thi
s | 531 // If the transaction is in progress, we should roll it back here, since thi
s |
| 531 // is our last opportunity to do something related to this transaction on th
e | 532 // is our last opportunity to do something related to this transaction on th
e |
| 532 // DB thread. Amongst other work, doCleanup() will clear m_sqliteTransaction | 533 // DB thread. Amongst other work, doCleanup() will clear m_sqliteTransaction |
| 533 // which invokes SQLiteTransaction's destructor, which will do the roll back | 534 // which invokes SQLiteTransaction's destructor, which will do the roll back |
| 534 // if necessary. | 535 // if necessary. |
| 535 doCleanup(); | 536 doCleanup(); |
| 536 } | 537 } |
| 537 | 538 |
| 538 SQLTransactionState SQLTransactionBackend::acquireLock() | 539 SQLTransactionState SQLTransactionBackend::acquireLock() |
| 539 { | 540 { |
| 540 m_database->transactionCoordinator()->acquireLock(this); | 541 m_database->transactionCoordinator()->acquireLock(this); |
| 541 return SQLTransactionState::Idle; | 542 return SQLTransactionState::Idle; |
| 542 } | 543 } |
| 543 | 544 |
| 544 void SQLTransactionBackend::lockAcquired() | 545 void SQLTransactionBackend::lockAcquired() |
| 545 { | 546 { |
| 546 m_lockAcquired = true; | 547 m_lockAcquired = true; |
| 547 requestTransitToState(SQLTransactionState::OpenTransactionAndPreflight); | 548 requestTransitToState(SQLTransactionState::OpenTransactionAndPreflight); |
| 548 } | 549 } |
| 549 | 550 |
| 550 SQLTransactionState SQLTransactionBackend::openTransactionAndPreflight() | 551 SQLTransactionState SQLTransactionBackend::openTransactionAndPreflight() |
| 551 { | 552 { |
| 553 DCHECK(database()->getDatabaseContext()->databaseThread()->isDatabaseThread(
)); |
| 552 ASSERT(!m_database->sqliteDatabase().transactionInProgress()); | 554 ASSERT(!m_database->sqliteDatabase().transactionInProgress()); |
| 553 ASSERT(m_lockAcquired); | 555 ASSERT(m_lockAcquired); |
| 554 | 556 |
| 555 WTF_LOG(StorageAPI, "Opening and preflighting transaction %p", this); | 557 WTF_LOG(StorageAPI, "Opening and preflighting transaction %p", this); |
| 556 | 558 |
| 557 // Set the maximum usage for this transaction if this transactions is not re
ad-only | 559 // Set the maximum usage for this transaction if this transactions is not re
ad-only |
| 558 if (!m_readOnly) | 560 if (!m_readOnly) |
| 559 m_database->sqliteDatabase().setMaximumSize(m_database->maximumSize()); | 561 m_database->sqliteDatabase().setMaximumSize(m_database->maximumSize()); |
| 560 | 562 |
| 561 ASSERT(!m_sqliteTransaction); | 563 ASSERT(!m_sqliteTransaction); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 608 // Spec 4.3.2.4: Invoke the transaction callback with the new SQLTransaction
object | 610 // Spec 4.3.2.4: Invoke the transaction callback with the new SQLTransaction
object |
| 609 if (m_hasCallback) | 611 if (m_hasCallback) |
| 610 return SQLTransactionState::DeliverTransactionCallback; | 612 return SQLTransactionState::DeliverTransactionCallback; |
| 611 | 613 |
| 612 // If we have no callback to make, skip pass to the state after: | 614 // If we have no callback to make, skip pass to the state after: |
| 613 return SQLTransactionState::RunStatements; | 615 return SQLTransactionState::RunStatements; |
| 614 } | 616 } |
| 615 | 617 |
| 616 SQLTransactionState SQLTransactionBackend::runStatements() | 618 SQLTransactionState SQLTransactionBackend::runStatements() |
| 617 { | 619 { |
| 620 DCHECK(database()->getDatabaseContext()->databaseThread()->isDatabaseThread(
)); |
| 618 ASSERT(m_lockAcquired); | 621 ASSERT(m_lockAcquired); |
| 619 SQLTransactionState nextState; | 622 SQLTransactionState nextState; |
| 620 | 623 |
| 621 // If there is a series of statements queued up that are all successful and
have no associated | 624 // If there is a series of statements queued up that are all successful and
have no associated |
| 622 // SQLStatementCallback objects, then we can burn through the queue | 625 // SQLStatementCallback objects, then we can burn through the queue |
| 623 do { | 626 do { |
| 624 if (m_shouldRetryCurrentStatement && !m_sqliteTransaction->wasRolledBack
BySqlite()) { | 627 if (m_shouldRetryCurrentStatement && !m_sqliteTransaction->wasRolledBack
BySqlite()) { |
| 625 m_shouldRetryCurrentStatement = false; | 628 m_shouldRetryCurrentStatement = false; |
| 626 // FIXME - Another place that needs fixing up after <rdar://problem/
5628468> is addressed. | 629 // FIXME - Another place that needs fixing up after <rdar://problem/
5628468> is addressed. |
| 627 // See ::openTransactionAndPreflight() for discussion | 630 // See ::openTransactionAndPreflight() for discussion |
| (...skipping 14 matching lines...) Expand all Loading... |
| 642 getNextStatement(); | 645 getNextStatement(); |
| 643 } | 646 } |
| 644 nextState = runCurrentStatementAndGetNextState(); | 647 nextState = runCurrentStatementAndGetNextState(); |
| 645 } while (nextState == SQLTransactionState::RunStatements); | 648 } while (nextState == SQLTransactionState::RunStatements); |
| 646 | 649 |
| 647 return nextState; | 650 return nextState; |
| 648 } | 651 } |
| 649 | 652 |
| 650 void SQLTransactionBackend::getNextStatement() | 653 void SQLTransactionBackend::getNextStatement() |
| 651 { | 654 { |
| 655 DCHECK(database()->getDatabaseContext()->databaseThread()->isDatabaseThread(
)); |
| 652 m_currentStatementBackend = nullptr; | 656 m_currentStatementBackend = nullptr; |
| 653 | 657 |
| 654 MutexLocker locker(m_statementMutex); | 658 MutexLocker locker(m_statementMutex); |
| 655 if (!m_statementQueue.isEmpty()) | 659 if (!m_statementQueue.isEmpty()) |
| 656 m_currentStatementBackend = m_statementQueue.takeFirst(); | 660 m_currentStatementBackend = m_statementQueue.takeFirst(); |
| 657 } | 661 } |
| 658 | 662 |
| 659 SQLTransactionState SQLTransactionBackend::runCurrentStatementAndGetNextState() | 663 SQLTransactionState SQLTransactionBackend::runCurrentStatementAndGetNextState() |
| 660 { | 664 { |
| 661 if (!m_currentStatementBackend) { | 665 if (!m_currentStatementBackend) { |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 818 } | 822 } |
| 819 | 823 |
| 820 SQLTransactionState SQLTransactionBackend::sendToFrontendState() | 824 SQLTransactionState SQLTransactionBackend::sendToFrontendState() |
| 821 { | 825 { |
| 822 ASSERT(m_nextState != SQLTransactionState::Idle); | 826 ASSERT(m_nextState != SQLTransactionState::Idle); |
| 823 m_frontend->requestTransitToState(m_nextState); | 827 m_frontend->requestTransitToState(m_nextState); |
| 824 return SQLTransactionState::Idle; | 828 return SQLTransactionState::Idle; |
| 825 } | 829 } |
| 826 | 830 |
| 827 } // namespace blink | 831 } // namespace blink |
| OLD | NEW |