• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 Computer, 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 "modules/webdatabase/DatabaseThread.h"
31 
32 #include "modules/webdatabase/Database.h"
33 #include "modules/webdatabase/DatabaseTask.h"
34 #include "modules/webdatabase/SQLTransactionClient.h"
35 #include "modules/webdatabase/SQLTransactionCoordinator.h"
36 #include "platform/Logging.h"
37 #include "public/platform/Platform.h"
38 #include "wtf/AutodrainedPool.h"
39 
40 namespace WebCore {
41 
DatabaseThread()42 DatabaseThread::DatabaseThread()
43     : m_transactionClient(adoptPtr(new SQLTransactionClient()))
44     , m_transactionCoordinator(adoptPtr(new SQLTransactionCoordinator()))
45     , m_cleanupSync(0)
46     , m_terminationRequested(false)
47 {
48 }
49 
~DatabaseThread()50 DatabaseThread::~DatabaseThread()
51 {
52     if (!m_terminationRequested)
53         requestTermination(0);
54     m_thread.clear();
55 }
56 
start()57 void DatabaseThread::start()
58 {
59     if (m_thread)
60         return;
61     m_thread = adoptPtr(blink::Platform::current()->createThread("WebCore: Database"));
62 }
63 
requestTermination(DatabaseTaskSynchronizer * cleanupSync)64 void DatabaseThread::requestTermination(DatabaseTaskSynchronizer *cleanupSync)
65 {
66     ASSERT(!m_terminationRequested);
67     m_terminationRequested = true;
68     m_cleanupSync = cleanupSync;
69     WTF_LOG(StorageAPI, "DatabaseThread %p was asked to terminate\n", this);
70     m_thread->postTask(new Task(WTF::bind(&DatabaseThread::cleanupDatabaseThread, this)));
71 }
72 
terminationRequested(DatabaseTaskSynchronizer * taskSynchronizer) const73 bool DatabaseThread::terminationRequested(DatabaseTaskSynchronizer* taskSynchronizer) const
74 {
75 #ifndef NDEBUG
76     if (taskSynchronizer)
77         taskSynchronizer->setHasCheckedForTermination();
78 #endif
79 
80     return m_terminationRequested;
81 }
82 
cleanupDatabaseThread()83 void DatabaseThread::cleanupDatabaseThread()
84 {
85     WTF_LOG(StorageAPI, "Cleaning up DatabaseThread %p", this);
86 
87     // Clean up the list of all pending transactions on this database thread
88     m_transactionCoordinator->shutdown();
89 
90     // Close the databases that we ran transactions on. This ensures that if any transactions are still open, they are rolled back and we don't leave the database in an
91     // inconsistent or locked state.
92     if (m_openDatabaseSet.size() > 0) {
93         // As the call to close will modify the original set, we must take a copy to iterate over.
94         DatabaseSet openSetCopy;
95         openSetCopy.swap(m_openDatabaseSet);
96         DatabaseSet::iterator end = openSetCopy.end();
97         for (DatabaseSet::iterator it = openSetCopy.begin(); it != end; ++it)
98             (*it).get()->close();
99     }
100 
101     if (m_cleanupSync) // Someone wanted to know when we were done cleaning up.
102         m_thread->postTask(new Task(WTF::bind(&DatabaseTaskSynchronizer::taskCompleted, m_cleanupSync)));
103 }
104 
recordDatabaseOpen(DatabaseBackend * database)105 void DatabaseThread::recordDatabaseOpen(DatabaseBackend* database)
106 {
107     ASSERT(isDatabaseThread());
108     ASSERT(database);
109     ASSERT(!m_openDatabaseSet.contains(database));
110     m_openDatabaseSet.add(database);
111 }
112 
recordDatabaseClosed(DatabaseBackend * database)113 void DatabaseThread::recordDatabaseClosed(DatabaseBackend* database)
114 {
115     ASSERT(isDatabaseThread());
116     ASSERT(database);
117     ASSERT(m_terminationRequested || m_openDatabaseSet.contains(database));
118     m_openDatabaseSet.remove(database);
119 }
120 
isDatabaseOpen(DatabaseBackend * database)121 bool DatabaseThread::isDatabaseOpen(DatabaseBackend* database)
122 {
123     ASSERT(isDatabaseThread());
124     ASSERT(database);
125     return !m_terminationRequested && m_openDatabaseSet.contains(database);
126 }
127 
scheduleTask(PassOwnPtr<DatabaseTask> task)128 void DatabaseThread::scheduleTask(PassOwnPtr<DatabaseTask> task)
129 {
130     ASSERT(m_thread);
131     ASSERT(!task->hasSynchronizer() || task->hasCheckedForTermination());
132     // WebThread takes ownership of the task.
133     m_thread->postTask(task.leakPtr());
134 }
135 
136 } // namespace WebCore
137