1/*
2 * Copyright (C) 2007, 2008, 2013 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of Apple Inc. ("Apple") nor the names of
14 * its contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include "config.h"
30#include "SQLTransactionBackend.h"
31
32#include "Database.h"
33#include "DatabaseAuthorizer.h"
34#include "DatabaseContext.h"
35#include "DatabaseThread.h"
36#include "DatabaseTracker.h"
37#include "Logging.h"
38#include "OriginLock.h"
39#include "SQLError.h"
40#include "SQLStatement.h"
41#include "SQLStatementCallback.h"
42#include "SQLStatementErrorCallback.h"
43#include "SQLTransaction.h"
44#include "SQLTransactionCoordinator.h"
45#include "SQLiteTransaction.h"
46#include <wtf/StdLibExtras.h>
47#include <wtf/text/WTFString.h>
48
49
50// How does a SQLTransaction work?
51// ==============================
52// The SQLTransaction is a state machine that executes a series of states / steps.
53//
54// The work of the transaction states are defined in section of 4.3.2 of the
55// webdatabase spec: http://dev.w3.org/html5/webdatabase/#processing-model
56//
57// the State Transition Graph at a glance:
58// ======================================
59//
60// Backend . Frontend
61// (works with SQLiteDatabase) . (works with Script)
62// =========================== . ===================
63// .
64// 1. Idle .
65// v .
66// 2. AcquireLock .
67// v .
68// 3. OpenTransactionAndPreflight ------------------------------------------.
69// | . |
70// `-------------------------------> 8. DeliverTransactionCallback --. |
71// . | v v
72// ,-------------------------------------' 9. DeliverTransactionErrorCallback +
73// | . ^ ^ ^ |
74// v . | | | |
75// 4. RunStatements -----------------------------------------------------' | | |
76// | ^ ^ | ^ | . | | |
77// |--------' | | | `------------> 10. DeliverStatementCallback +-----' | |
78// | | | `---------------------------------------------' | |
79// | | `-----------------> 11. DeliverQuotaIncreaseCallback + | |
80// | `-----------------------------------------------------' | |
81// v . | |
82// 5. PostflightAndCommit --+--------------------------------------------------' |
83// |----------> 12. DeliverSuccessCallback + |
84// ,--------------------' . | |
85// v . | |
86// 6. CleanupAndTerminate <-----------------------------------------' |
87// v ^ . |
88// 0. End | . |
89// | . |
90// 7: CleanupAfterTransactionErrorCallback <----------------------------'
91// .
92//
93// the States and State Transitions:
94// ================================
95// 0. SQLTransactionState::End
96// - the end state.
97//
98// 1. SQLTransactionState::Idle
99// - placeholder state while waiting on frontend/backend, etc. See comment on
100// "State transitions between SQLTransaction and SQLTransactionBackend"
101// below.
102//
103// 2. SQLTransactionState::AcquireLock (runs in backend)
104// - this is the start state.
105// - acquire the "lock".
106// - on "lock" acquisition, goto SQLTransactionState::OpenTransactionAndPreflight.
107//
108// 3. SQLTransactionState::openTransactionAndPreflight (runs in backend)
109// - Sets up an SQLiteTransaction.
110// - begin the SQLiteTransaction.
111// - call the SQLTransactionWrapper preflight if available.
112// - schedule script callback.
113// - on error, goto SQLTransactionState::DeliverTransactionErrorCallback.
114// - goto SQLTransactionState::DeliverTransactionCallback.
115//
116// 4. SQLTransactionState::DeliverTransactionCallback (runs in frontend)
117// - invoke the script function callback() if available.
118// - on error, goto SQLTransactionState::DeliverTransactionErrorCallback.
119// - goto SQLTransactionState::RunStatements.
120//
121// 5. SQLTransactionState::DeliverTransactionErrorCallback (runs in frontend)
122// - invoke the script function errorCallback if available.
123// - goto SQLTransactionState::CleanupAfterTransactionErrorCallback.
124//
125// 6. SQLTransactionState::RunStatements (runs in backend)
126// - while there are statements {
127// - run a statement.
128// - if statementCallback is available, goto SQLTransactionState::DeliverStatementCallback.
129// - on error,
130// goto SQLTransactionState::DeliverQuotaIncreaseCallback, or
131// goto SQLTransactionState::DeliverStatementCallback, or
132// goto SQLTransactionState::deliverTransactionErrorCallback.
133// }
134// - goto SQLTransactionState::PostflightAndCommit.
135//
136// 7. SQLTransactionState::DeliverStatementCallback (runs in frontend)
137// - invoke script statement callback (assume available).
138// - on error, goto SQLTransactionState::DeliverTransactionErrorCallback.
139// - goto SQLTransactionState::RunStatements.
140//
141// 8. SQLTransactionState::DeliverQuotaIncreaseCallback (runs in frontend)
142// - give client a chance to increase the quota.
143// - goto SQLTransactionState::RunStatements.
144//
145// 9. SQLTransactionState::PostflightAndCommit (runs in backend)
146// - call the SQLTransactionWrapper postflight if available.
147// - commit the SQLiteTansaction.
148// - on error, goto SQLTransactionState::DeliverTransactionErrorCallback.
149// - if successCallback is available, goto SQLTransactionState::DeliverSuccessCallback.
150// else goto SQLTransactionState::CleanupAndTerminate.
151//
152// 10. SQLTransactionState::DeliverSuccessCallback (runs in frontend)
153// - invoke the script function successCallback() if available.
154// - goto SQLTransactionState::CleanupAndTerminate.
155//
156// 11. SQLTransactionState::CleanupAndTerminate (runs in backend)
157// - stop and clear the SQLiteTransaction.
158// - release the "lock".
159// - goto SQLTransactionState::End.
160//
161// 12. SQLTransactionState::CleanupAfterTransactionErrorCallback (runs in backend)
162// - rollback the SQLiteTransaction.
163// - goto SQLTransactionState::CleanupAndTerminate.
164//
165// State transitions between SQLTransaction and SQLTransactionBackend
166// ==================================================================
167// As shown above, there are state transitions that crosses the boundary between
168// the frontend and backend. For example,
169//
170// OpenTransactionAndPreflight (state 3 in the backend)
171// transitions to DeliverTransactionCallback (state 8 in the frontend),
172// which in turn transitions to RunStatements (state 4 in the backend).
173//
174// This cross boundary transition is done by posting transition requests to the
175// other side and letting the other side's state machine execute the state
176// transition in the appropriate thread (i.e. the script thread for the frontend,
177// and the database thread for the backend).
178//
179// Logically, the state transitions work as shown in the graph above. But
180// physically, the transition mechanism uses the Idle state (both in the frontend
181// and backend) as a waiting state for further activity. For example, taking a
182// closer look at the 3 state transition example above, what actually happens
183// is as follows:
184//
185// Step 1:
186// ======
187// In the frontend thread:
188// - waiting quietly is Idle. Not doing any work.
189//
190// In the backend:
191// - is in OpenTransactionAndPreflight, and doing its work.
192// - when done, it transits to the backend DeliverTransactionCallback.
193// - the backend DeliverTransactionCallback sends a request to the frontend
194// to transit to DeliverTransactionCallback, and then itself transits to
195// Idle.
196//
197// Step 2:
198// ======
199// In the frontend thread:
200// - transits to DeliverTransactionCallback and does its work.
201// - when done, it transits to the frontend RunStatements.
202// - the frontend RunStatements sends a request to the backend to transit
203// to RunStatements, and then itself transits to Idle.
204//
205// In the backend:
206// - waiting quietly in Idle.
207//
208// Step 3:
209// ======
210// In the frontend thread:
211// - waiting quietly is Idle. Not doing any work.
212//
213// In the backend:
214// - transits to RunStatements, and does its work.
215// ...
216//
217// So, when the frontend or backend are not active, they will park themselves in
218// their Idle states. This means their m_nextState is set to Idle, but they never
219// actually run the corresponding state function. Note: for both the frontend and
220// backend, the state function for Idle is unreachableState().
221//
222// The states that send a request to their peer across the front/back boundary
223// are implemented with just 2 functions: SQLTransaction::sendToBackendState()
224// and SQLTransactionBackend::sendToFrontendState(). These state functions do
225// nothing but sends a request to the other side to transit to the current
226// state (indicated by m_nextState), and then transits itself to the Idle state
227// to wait for further action.
228
229
230// The Life-Cycle of a SQLTransaction i.e. Who's keeping the SQLTransaction alive?
231// ==============================================================================
232// The RefPtr chain goes something like this:
233//
234// At birth (in DatabaseBackend::runTransaction()):
235// ====================================================
236// DatabaseBackend // Deque<RefPtr<SQLTransactionBackend>> m_transactionQueue points to ...
237// --> SQLTransactionBackend // RefPtr<SQLTransaction> m_frontend points to ...
238// --> SQLTransaction // RefPtr<SQLTransactionBackend> m_backend points to ...
239// --> SQLTransactionBackend // which is a circular reference.
240//
241// Note: there's a circular reference between the SQLTransaction front-end and
242// back-end. This circular reference is established in the constructor of the
243// SQLTransactionBackend. The circular reference will be broken by calling
244// doCleanup() to nullify m_frontend. This is done at the end of the transaction's
245// clean up state (i.e. when the transaction should no longer be in use thereafter),
246// or if the database was interrupted. See comments on "What happens if a transaction
247// is interrupted?" below for details.
248//
249// After scheduling the transaction with the DatabaseThread (DatabaseBackend::scheduleTransaction()):
250// ======================================================================================================
251// DatabaseThread // MessageQueue<DatabaseTask> m_queue points to ...
252// --> DatabaseTransactionTask // RefPtr<SQLTransactionBackend> m_transaction points to ...
253// --> SQLTransactionBackend // RefPtr<SQLTransaction> m_frontend points to ...
254// --> SQLTransaction // RefPtr<SQLTransactionBackend> m_backend points to ...
255// --> SQLTransactionBackend // which is a circular reference.
256//
257// When executing the transaction (in DatabaseThread::databaseThread()):
258// ====================================================================
259// std::unique_ptr<DatabaseTask> task; // points to ...
260// --> DatabaseTransactionTask // RefPtr<SQLTransactionBackend> m_transaction points to ...
261// --> SQLTransactionBackend // RefPtr<SQLTransaction> m_frontend;
262// --> SQLTransaction // RefPtr<SQLTransactionBackend> m_backend points to ...
263// --> SQLTransactionBackend // which is a circular reference.
264//
265// At the end of cleanupAndTerminate():
266// ===================================
267// At the end of the cleanup state, the SQLTransactionBackend::m_frontend is nullified.
268// If by then, a JSObject wrapper is referring to the SQLTransaction, then the reference
269// chain looks like this:
270//
271// JSObjectWrapper
272// --> SQLTransaction // in RefPtr<SQLTransactionBackend> m_backend points to ...
273// --> SQLTransactionBackend // which no longer points back to its SQLTransaction.
274//
275// When the GC collects the corresponding JSObject, the above chain will be cleaned up
276// and deleted.
277//
278// If there is no JSObject wrapper referring to the SQLTransaction when the cleanup
279// states nullify SQLTransactionBackend::m_frontend, the SQLTransaction will deleted then.
280// However, there will still be a DatabaseTask pointing to the SQLTransactionBackend (see
281// the "When executing the transaction" chain above). This will keep the
282// SQLTransactionBackend alive until DatabaseThread::databaseThread() releases its
283// task std::unique_ptr.
284//
285// What happens if a transaction is interrupted?
286// ============================================
287// If the transaction is interrupted half way, it won't get to run to state
288// CleanupAndTerminate, and hence, would not have called SQLTransactionBackend's
289// doCleanup(). doCleanup() is where we nullify SQLTransactionBackend::m_frontend
290// to break the reference cycle between the frontend and backend. Hence, we need
291// to cleanup the transaction by other means.
292//
293// Note: calling SQLTransactionBackend::notifyDatabaseThreadIsShuttingDown()
294// is effectively the same as calling SQLTransactionBackend::doClean().
295//
296// In terms of who needs to call doCleanup(), there are 5 phases in the
297// SQLTransactionBackend life-cycle. These are the phases and how the clean
298// up is done:
299//
300// Phase 1. After Birth, before scheduling
301//
302// - To clean up, DatabaseThread::databaseThread() will call
303// DatabaseBackend::close() during its shutdown.
304// - DatabaseBackend::close() will iterate
305// DatabaseBackend::m_transactionQueue and call
306// notifyDatabaseThreadIsShuttingDown() on each transaction there.
307//
308// Phase 2. After scheduling, before state AcquireLock
309//
310// - If the interruption occures before the DatabaseTransactionTask is
311// scheduled in DatabaseThread::m_queue but hasn't gotten to execute
312// (i.e. DatabaseTransactionTask::performTask() has not been called),
313// then the DatabaseTransactionTask may get destructed before it ever
314// gets to execute.
315// - To clean up, the destructor will check if the task's m_wasExecuted is
316// set. If not, it will call notifyDatabaseThreadIsShuttingDown() on
317// the task's transaction.
318//
319// Phase 3. After state AcquireLock, before "lockAcquired"
320//
321// - In this phase, the transaction would have been added to the
322// SQLTransactionCoordinator's CoordinationInfo's pendingTransactions.
323// - To clean up, during shutdown, DatabaseThread::databaseThread() calls
324// SQLTransactionCoordinator::shutdown(), which calls
325// notifyDatabaseThreadIsShuttingDown().
326//
327// Phase 4: After "lockAcquired", before state CleanupAndTerminate
328//
329// - In this phase, the transaction would have been added either to the
330// SQLTransactionCoordinator's CoordinationInfo's activeWriteTransaction
331// or activeReadTransactions.
332// - To clean up, during shutdown, DatabaseThread::databaseThread() calls
333// SQLTransactionCoordinator::shutdown(), which calls
334// notifyDatabaseThreadIsShuttingDown().
335//
336// Phase 5: After state CleanupAndTerminate
337//
338// - This is how a transaction ends normally.
339// - state CleanupAndTerminate calls doCleanup().
340
341namespace WebCore {
342
343SQLTransactionBackend::SQLTransactionBackend(SQLTransaction& frontend)
344 : m_frontend(frontend)
345{
346 m_requestedState = SQLTransactionState::AcquireLock;
347}
348
349SQLTransactionBackend::~SQLTransactionBackend()
350{
351 ASSERT(!m_frontend.m_sqliteTransaction);
352}
353
354void SQLTransactionBackend::doCleanup()
355{
356 ASSERT(m_frontend.database().databaseThread().getThread() == &Thread::current());
357
358 m_frontend.releaseOriginLockIfNeeded();
359
360 LockHolder locker(m_frontend.m_statementMutex);
361 m_frontend.m_statementQueue.clear();
362
363 if (m_frontend.m_sqliteTransaction) {
364 // In the event we got here because of an interruption or error (i.e. if
365 // the transaction is in progress), we should roll it back here. Clearing
366 // m_sqliteTransaction invokes SQLiteTransaction's destructor which does
367 // just that. We might as well do this unconditionally and free up its
368 // resources because we're already terminating.
369 m_frontend.m_sqliteTransaction = nullptr;
370 }
371
372 // Release the lock on this database
373 if (m_frontend.m_lockAcquired)
374 m_frontend.m_database->transactionCoordinator()->releaseLock(m_frontend);
375
376 // Do some aggresive clean up here except for m_database.
377 //
378 // We can't clear m_database here because the frontend may asynchronously
379 // invoke SQLTransactionBackend::requestTransitToState(), and that function
380 // uses m_database to schedule a state transition. This may occur because
381 // the frontend (being in another thread) may already be on the way to
382 // requesting our next state before it detects an interruption.
383 //
384 // There is no harm in letting it finish making the request. It'll set
385 // m_requestedState, but we won't execute a transition to that state because
386 // we've already shut down the transaction.
387 //
388 // We also can't clear m_currentStatementBackend and m_transactionError.
389 // m_currentStatementBackend may be accessed asynchronously by the
390 // frontend's deliverStatementCallback() state. Similarly,
391 // m_transactionError may be accessed by deliverTransactionErrorCallback().
392 // This occurs if requests for transition to those states have already been
393 // registered with the frontend just prior to a clean up request arriving.
394 //
395 // So instead, let our destructor handle their clean up since this
396 // SQLTransactionBackend is guaranteed to not destruct until the frontend
397 // is also destructing.
398
399 m_frontend.m_wrapper = nullptr;
400}
401
402SQLTransactionBackend::StateFunction SQLTransactionBackend::stateFunctionFor(SQLTransactionState state)
403{
404 static const StateFunction stateFunctions[] = {
405 &SQLTransactionBackend::unreachableState, // 0. end
406 &SQLTransactionBackend::unreachableState, // 1. idle
407 &SQLTransactionBackend::acquireLock, // 2.
408 &SQLTransactionBackend::openTransactionAndPreflight, // 3.
409 &SQLTransactionBackend::runStatements, // 4.
410 &SQLTransactionBackend::unreachableState, // 5. postflightAndCommit
411 &SQLTransactionBackend::cleanupAndTerminate, // 6.
412 &SQLTransactionBackend::cleanupAfterTransactionErrorCallback, // 7.
413 &SQLTransactionBackend::unreachableState, // 8. deliverTransactionCallback
414 &SQLTransactionBackend::unreachableState, // 9. deliverTransactionErrorCallback
415 &SQLTransactionBackend::unreachableState, // 10. deliverStatementCallback
416 &SQLTransactionBackend::unreachableState, // 11. deliverQuotaIncreaseCallback
417 &SQLTransactionBackend::unreachableState // 12. deliverSuccessCallback
418 };
419
420 ASSERT(WTF_ARRAY_LENGTH(stateFunctions) == static_cast<int>(SQLTransactionState::NumberOfStates));
421 ASSERT(state < SQLTransactionState::NumberOfStates);
422
423 return stateFunctions[static_cast<int>(state)];
424}
425
426void SQLTransactionBackend::computeNextStateAndCleanupIfNeeded()
427{
428 // Only honor the requested state transition if we're not supposed to be
429 // cleaning up and shutting down:
430 if (m_frontend.m_database->opened()) {
431 setStateToRequestedState();
432 ASSERT(m_nextState == SQLTransactionState::AcquireLock
433 || m_nextState == SQLTransactionState::OpenTransactionAndPreflight
434 || m_nextState == SQLTransactionState::RunStatements
435 || m_nextState == SQLTransactionState::PostflightAndCommit
436 || m_nextState == SQLTransactionState::CleanupAndTerminate
437 || m_nextState == SQLTransactionState::CleanupAfterTransactionErrorCallback);
438
439 LOG(StorageAPI, "State %s\n", nameForSQLTransactionState(m_nextState));
440 return;
441 }
442
443 // If we get here, then we should be shutting down. Do clean up if needed:
444 if (m_nextState == SQLTransactionState::End)
445 return;
446 m_nextState = SQLTransactionState::End;
447
448 // If the database was stopped, don't do anything and cancel queued work
449 LOG(StorageAPI, "Database was stopped or interrupted - cancelling work for this transaction");
450
451 // The current SQLite transaction should be stopped, as well
452 if (m_frontend.m_sqliteTransaction) {
453 m_frontend.m_sqliteTransaction->stop();
454 m_frontend.m_sqliteTransaction = nullptr;
455 }
456
457 // Terminate the frontend state machine. This also gets the frontend to
458 // call computeNextStateAndCleanupIfNeeded() and clear its wrappers
459 // if needed.
460 m_frontend.requestTransitToState(SQLTransactionState::End);
461
462 // Redirect to the end state to abort, clean up, and end the transaction.
463 doCleanup();
464}
465
466void SQLTransactionBackend::notifyDatabaseThreadIsShuttingDown()
467{
468 ASSERT(m_frontend.database().databaseThread().getThread() == &Thread::current());
469
470 // If the transaction is in progress, we should roll it back here, since this
471 // is our last opportunity to do something related to this transaction on the
472 // DB thread. Amongst other work, doCleanup() will clear m_sqliteTransaction
473 // which invokes SQLiteTransaction's destructor, which will do the roll back
474 // if necessary.
475 doCleanup();
476}
477
478void SQLTransactionBackend::acquireLock()
479{
480 m_frontend.acquireLock();
481}
482
483void SQLTransactionBackend::openTransactionAndPreflight()
484{
485 m_frontend.openTransactionAndPreflight();
486}
487
488void SQLTransactionBackend::runStatements()
489{
490 m_frontend.runStatements();
491}
492
493void SQLTransactionBackend::cleanupAndTerminate()
494{
495 m_frontend.cleanupAndTerminate();
496}
497
498void SQLTransactionBackend::cleanupAfterTransactionErrorCallback()
499{
500 m_frontend.cleanupAfterTransactionErrorCallback();
501}
502
503// requestTransitToState() can be called from the frontend. Hence, it should
504// NOT be modifying SQLTransactionBackend in general. The only safe field to
505// modify is m_requestedState which is meant for this purpose.
506void SQLTransactionBackend::requestTransitToState(SQLTransactionState nextState)
507{
508 LOG(StorageAPI, "Scheduling %s for transaction %p\n", nameForSQLTransactionState(nextState), this);
509 m_requestedState = nextState;
510 ASSERT(m_requestedState != SQLTransactionState::End);
511 m_frontend.m_database->scheduleTransactionStep(m_frontend);
512}
513
514// This state function is used as a stub function to plug unimplemented states
515// in the state dispatch table. They are unimplemented because they should
516// never be reached in the course of correct execution.
517void SQLTransactionBackend::unreachableState()
518{
519 ASSERT_NOT_REACHED();
520}
521
522} // namespace WebCore
523