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#ifndef DatabaseTask_h 29#define DatabaseTask_h 30 31#if ENABLE(SQL_DATABASE) 32 33#include "DatabaseBackend.h" 34#include "DatabaseBasicTypes.h" 35#include "DatabaseError.h" 36#include "SQLTransactionBackend.h" 37#include <wtf/PassRefPtr.h> 38#include <wtf/Threading.h> 39#include <wtf/Vector.h> 40#include <wtf/text/WTFString.h> 41 42namespace WebCore { 43 44// Can be used to wait until DatabaseTask is completed. 45// Has to be passed into DatabaseTask::create to be associated with the task. 46class DatabaseTaskSynchronizer { 47 WTF_MAKE_NONCOPYABLE(DatabaseTaskSynchronizer); 48public: 49 DatabaseTaskSynchronizer(); 50 51 // Called from main thread to wait until task is completed. 52 void waitForTaskCompletion(); 53 54 // Called by the task. 55 void taskCompleted(); 56 57#ifndef NDEBUG 58 bool hasCheckedForTermination() const { return m_hasCheckedForTermination; } 59 void setHasCheckedForTermination() { m_hasCheckedForTermination = true; } 60#endif 61 62private: 63 bool m_taskCompleted; 64 Mutex m_synchronousMutex; 65 ThreadCondition m_synchronousCondition; 66#ifndef NDEBUG 67 bool m_hasCheckedForTermination; 68#endif 69}; 70 71class DatabaseTask { 72 WTF_MAKE_NONCOPYABLE(DatabaseTask); WTF_MAKE_FAST_ALLOCATED; 73public: 74 virtual ~DatabaseTask(); 75 76#if PLATFORM(IOS) 77 virtual bool shouldPerformWhilePaused() const = 0; 78#endif 79 80 void performTask(); 81 82 DatabaseBackend* database() const { return m_database; } 83#ifndef NDEBUG 84 bool hasSynchronizer() const { return m_synchronizer; } 85 bool hasCheckedForTermination() const { return m_synchronizer->hasCheckedForTermination(); } 86#endif 87 88protected: 89 DatabaseTask(DatabaseBackend*, DatabaseTaskSynchronizer*); 90 91private: 92 virtual void doPerformTask() = 0; 93 94 DatabaseBackend* m_database; 95 DatabaseTaskSynchronizer* m_synchronizer; 96 97#if !LOG_DISABLED 98 virtual const char* debugTaskName() const = 0; 99 bool m_complete; 100#endif 101}; 102 103class DatabaseBackend::DatabaseOpenTask : public DatabaseTask { 104public: 105 static std::unique_ptr<DatabaseOpenTask> create(DatabaseBackend* db, bool setVersionInNewDatabase, DatabaseTaskSynchronizer* synchronizer, DatabaseError& error, String& errorMessage, bool& success) 106 { 107 return std::unique_ptr<DatabaseOpenTask>(new DatabaseOpenTask(db, setVersionInNewDatabase, synchronizer, error, errorMessage, success)); 108 } 109 110#if PLATFORM(IOS) 111 virtual bool shouldPerformWhilePaused() const override { return true; } 112#endif 113 114private: 115 DatabaseOpenTask(DatabaseBackend*, bool setVersionInNewDatabase, DatabaseTaskSynchronizer*, DatabaseError&, String& errorMessage, bool& success); 116 117 virtual void doPerformTask(); 118#if !LOG_DISABLED 119 virtual const char* debugTaskName() const; 120#endif 121 122 bool m_setVersionInNewDatabase; 123 DatabaseError& m_error; 124 String& m_errorMessage; 125 bool& m_success; 126}; 127 128class DatabaseBackend::DatabaseCloseTask : public DatabaseTask { 129public: 130 static std::unique_ptr<DatabaseCloseTask> create(DatabaseBackend* db, DatabaseTaskSynchronizer* synchronizer) 131 { 132 return std::unique_ptr<DatabaseCloseTask>(new DatabaseCloseTask(db, synchronizer)); 133 } 134 135#if PLATFORM(IOS) 136 virtual bool shouldPerformWhilePaused() const override { return true; } 137#endif 138 139private: 140 DatabaseCloseTask(DatabaseBackend*, DatabaseTaskSynchronizer*); 141 142 virtual void doPerformTask(); 143#if !LOG_DISABLED 144 virtual const char* debugTaskName() const; 145#endif 146}; 147 148class DatabaseBackend::DatabaseTransactionTask : public DatabaseTask { 149public: 150 virtual ~DatabaseTransactionTask(); 151 152 // Transaction task is never synchronous, so no 'synchronizer' parameter. 153 static std::unique_ptr<DatabaseTransactionTask> create(PassRefPtr<SQLTransactionBackend> transaction) 154 { 155 return std::unique_ptr<DatabaseTransactionTask>(new DatabaseTransactionTask(transaction)); 156 } 157 158#if PLATFORM(IOS) 159 virtual bool shouldPerformWhilePaused() const override; 160#endif 161 162 SQLTransactionBackend* transaction() const { return m_transaction.get(); } 163 164private: 165 explicit DatabaseTransactionTask(PassRefPtr<SQLTransactionBackend>); 166 167 virtual void doPerformTask(); 168#if !LOG_DISABLED 169 virtual const char* debugTaskName() const; 170#endif 171 172 RefPtr<SQLTransactionBackend> m_transaction; 173 bool m_didPerformTask; 174}; 175 176class DatabaseBackend::DatabaseTableNamesTask : public DatabaseTask { 177public: 178 static std::unique_ptr<DatabaseTableNamesTask> create(DatabaseBackend* db, DatabaseTaskSynchronizer* synchronizer, Vector<String>& names) 179 { 180 return std::unique_ptr<DatabaseTableNamesTask>(new DatabaseTableNamesTask(db, synchronizer, names)); 181 } 182 183#if PLATFORM(IOS) 184 virtual bool shouldPerformWhilePaused() const override { return true; } 185#endif 186 187private: 188 DatabaseTableNamesTask(DatabaseBackend*, DatabaseTaskSynchronizer*, Vector<String>& names); 189 190 virtual void doPerformTask(); 191#if !LOG_DISABLED 192 virtual const char* debugTaskName() const; 193#endif 194 195 Vector<String>& m_tableNames; 196}; 197 198} // namespace WebCore 199 200#endif // ENABLE(SQL_DATABASE) 201 202#endif // DatabaseTask_h 203