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 #include "config.h" 29 #include "modules/webdatabase/DatabaseTask.h" 30 31 #include "core/platform/Logging.h" 32 #include "modules/webdatabase/Database.h" 33 #include "modules/webdatabase/DatabaseBackend.h" 34 35 namespace WebCore { 36 37 DatabaseTaskSynchronizer::DatabaseTaskSynchronizer() 38 : m_taskCompleted(false) 39 #ifndef NDEBUG 40 , m_hasCheckedForTermination(false) 41 #endif 42 { 43 } 44 45 void DatabaseTaskSynchronizer::waitForTaskCompletion() 46 { 47 m_synchronousMutex.lock(); 48 while (!m_taskCompleted) 49 m_synchronousCondition.wait(m_synchronousMutex); 50 m_synchronousMutex.unlock(); 51 } 52 53 void DatabaseTaskSynchronizer::taskCompleted() 54 { 55 m_synchronousMutex.lock(); 56 m_taskCompleted = true; 57 m_synchronousCondition.signal(); 58 m_synchronousMutex.unlock(); 59 } 60 61 DatabaseTask::DatabaseTask(DatabaseBackend* database, DatabaseTaskSynchronizer* synchronizer) 62 : m_database(database) 63 , m_synchronizer(synchronizer) 64 #if !LOG_DISABLED 65 , m_complete(false) 66 #endif 67 { 68 } 69 70 DatabaseTask::~DatabaseTask() 71 { 72 #if !LOG_DISABLED 73 ASSERT(m_complete || !m_synchronizer); 74 #endif 75 } 76 77 void DatabaseTask::performTask() 78 { 79 // Database tasks are meant to be used only once, so make sure this one hasn't been performed before. 80 #if !LOG_DISABLED 81 ASSERT(!m_complete); 82 #endif 83 84 LOG(StorageAPI, "Performing %s %p\n", debugTaskName(), this); 85 86 m_database->resetAuthorizer(); 87 doPerformTask(); 88 89 if (m_synchronizer) 90 m_synchronizer->taskCompleted(); 91 92 #if !LOG_DISABLED 93 m_complete = true; 94 #endif 95 } 96 97 // *** DatabaseOpenTask *** 98 // Opens the database file and verifies the version matches the expected version. 99 100 DatabaseBackend::DatabaseOpenTask::DatabaseOpenTask(DatabaseBackend* database, bool setVersionInNewDatabase, DatabaseTaskSynchronizer* synchronizer, DatabaseError& error, String& errorMessage, bool& success) 101 : DatabaseTask(database, synchronizer) 102 , m_setVersionInNewDatabase(setVersionInNewDatabase) 103 , m_error(error) 104 , m_errorMessage(errorMessage) 105 , m_success(success) 106 { 107 ASSERT(synchronizer); // A task with output parameters is supposed to be synchronous. 108 } 109 110 void DatabaseBackend::DatabaseOpenTask::doPerformTask() 111 { 112 String errorMessage; 113 m_success = database()->performOpenAndVerify(m_setVersionInNewDatabase, m_error, errorMessage); 114 if (!m_success) 115 m_errorMessage = errorMessage.isolatedCopy(); 116 } 117 118 #if !LOG_DISABLED 119 const char* DatabaseBackend::DatabaseOpenTask::debugTaskName() const 120 { 121 return "DatabaseOpenTask"; 122 } 123 #endif 124 125 // *** DatabaseCloseTask *** 126 // Closes the database. 127 128 DatabaseBackend::DatabaseCloseTask::DatabaseCloseTask(DatabaseBackend* database, DatabaseTaskSynchronizer* synchronizer) 129 : DatabaseTask(database, synchronizer) 130 { 131 } 132 133 void DatabaseBackend::DatabaseCloseTask::doPerformTask() 134 { 135 Database::from(database())->close(); 136 } 137 138 #if !LOG_DISABLED 139 const char* DatabaseBackend::DatabaseCloseTask::debugTaskName() const 140 { 141 return "DatabaseCloseTask"; 142 } 143 #endif 144 145 // *** DatabaseTransactionTask *** 146 // Starts a transaction that will report its results via a callback. 147 148 DatabaseBackend::DatabaseTransactionTask::DatabaseTransactionTask(PassRefPtr<SQLTransactionBackend> transaction) 149 : DatabaseTask(Database::from(transaction->database()), 0) 150 , m_transaction(transaction) 151 , m_didPerformTask(false) 152 { 153 } 154 155 DatabaseBackend::DatabaseTransactionTask::~DatabaseTransactionTask() 156 { 157 // If the task is being destructed without the transaction ever being run, 158 // then we must either have an error or an interruption. Give the 159 // transaction a chance to clean up since it may not have been able to 160 // run to its clean up state. 161 162 // Transaction phase 2 cleanup. See comment on "What happens if a 163 // transaction is interrupted?" at the top of SQLTransactionBackend.cpp. 164 165 if (!m_didPerformTask) 166 m_transaction->notifyDatabaseThreadIsShuttingDown(); 167 } 168 169 void DatabaseBackend::DatabaseTransactionTask::doPerformTask() 170 { 171 m_transaction->performNextStep(); 172 m_didPerformTask = true; 173 } 174 175 #if !LOG_DISABLED 176 const char* DatabaseBackend::DatabaseTransactionTask::debugTaskName() const 177 { 178 return "DatabaseTransactionTask"; 179 } 180 #endif 181 182 // *** DatabaseTableNamesTask *** 183 // Retrieves a list of all tables in the database - for WebInspector support. 184 185 DatabaseBackend::DatabaseTableNamesTask::DatabaseTableNamesTask(DatabaseBackend* database, DatabaseTaskSynchronizer* synchronizer, Vector<String>& names) 186 : DatabaseTask(database, synchronizer) 187 , m_tableNames(names) 188 { 189 ASSERT(synchronizer); // A task with output parameters is supposed to be synchronous. 190 } 191 192 void DatabaseBackend::DatabaseTableNamesTask::doPerformTask() 193 { 194 m_tableNames = Database::from(database())->performGetTableNames(); 195 } 196 197 #if !LOG_DISABLED 198 const char* DatabaseBackend::DatabaseTableNamesTask::debugTaskName() const 199 { 200 return "DatabaseTableNamesTask"; 201 } 202 #endif 203 204 } // namespace WebCore 205