Changeset 243939 in webkit


Ignore:
Timestamp:
Apr 5, 2019 11:06:09 AM (5 years ago)
Author:
sihui_liu@apple.com
Message:

[iOS] Web process gets suspended while holding locked database files
https://bugs.webkit.org/show_bug.cgi?id=196519
<rdar://problem/49531797>

Reviewed by Chris Dumez.

Source/WebCore:

We should close all databases and make sure not open new databases when web process is ready to suspend.

  • platform/sql/SQLiteDatabase.cpp:

(WebCore::SQLiteDatabase::setIsDatabaseOpeningForbidden):
(WebCore::SQLiteDatabase::open):

  • platform/sql/SQLiteDatabase.h:
  • platform/sql/SQLiteDatabaseTracker.cpp:

(WebCore::SQLiteDatabaseTracker::setClient):
(WebCore::SQLiteDatabaseTracker::incrementTransactionInProgressCount):
(WebCore::SQLiteDatabaseTracker::decrementTransactionInProgressCount):
(WebCore::SQLiteDatabaseTracker::hasTransactionInProgress):

Source/WebKit:

  • Shared/WebSQLiteDatabaseTracker.cpp:

(WebKit::WebSQLiteDatabaseTracker::~WebSQLiteDatabaseTracker):

  • Shared/WebSQLiteDatabaseTracker.h:
  • WebProcess/WebProcess.cpp:

(WebKit::m_webSQLiteDatabaseTracker):
(WebKit::WebProcess::actualPrepareToSuspend):
(WebKit::WebProcess::processWillSuspendImminently):
(WebKit::WebProcess::cancelPrepareToSuspend):
(WebKit::WebProcess::processDidResume):

  • WebProcess/WebProcess.h:
Location:
trunk/Source
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r243934 r243939  
     12019-04-05  Sihui Liu  <sihui_liu@apple.com>
     2
     3        [iOS] Web process gets suspended while holding locked database files
     4        https://bugs.webkit.org/show_bug.cgi?id=196519
     5        <rdar://problem/49531797>
     6
     7        Reviewed by Chris Dumez.
     8
     9        We should close all databases and make sure not open new databases when web process is ready to suspend.
     10
     11        * platform/sql/SQLiteDatabase.cpp:
     12        (WebCore::SQLiteDatabase::setIsDatabaseOpeningForbidden):
     13        (WebCore::SQLiteDatabase::open):
     14        * platform/sql/SQLiteDatabase.h:
     15        * platform/sql/SQLiteDatabaseTracker.cpp:
     16        (WebCore::SQLiteDatabaseTracker::setClient):
     17        (WebCore::SQLiteDatabaseTracker::incrementTransactionInProgressCount):
     18        (WebCore::SQLiteDatabaseTracker::decrementTransactionInProgressCount):
     19        (WebCore::SQLiteDatabaseTracker::hasTransactionInProgress):
     20
    1212019-04-05  Commit Queue  <commit-queue@webkit.org>
    222
  • trunk/Source/WebCore/platform/sql/SQLiteDatabase.cpp

    r243085 r243939  
    7272}
    7373
     74static bool isDatabaseOpeningForbidden = false;
     75static Lock isDatabaseOpeningForbiddenMutex;
     76
     77void SQLiteDatabase::setIsDatabaseOpeningForbidden(bool isForbidden)
     78{
     79    std::lock_guard<Lock> lock(isDatabaseOpeningForbiddenMutex);
     80    isDatabaseOpeningForbidden = isForbidden;
     81}
     82
    7483SQLiteDatabase::SQLiteDatabase() = default;
    7584
     
    8594    close();
    8695
    87     int flags = SQLITE_OPEN_AUTOPROXY;
    88     switch (openMode) {
    89     case OpenMode::ReadOnly:
    90         flags |= SQLITE_OPEN_READONLY;
    91         break;
    92     case OpenMode::ReadWrite:
    93         flags |= SQLITE_OPEN_READWRITE;
    94         break;
    95     case OpenMode::ReadWriteCreate:
    96         flags |= SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
    97         break;
    98     }
    99 
    100     m_openError = sqlite3_open_v2(FileSystem::fileSystemRepresentation(filename).data(), &m_db, flags, nullptr);
    101     if (m_openError != SQLITE_OK) {
    102         m_openErrorMessage = m_db ? sqlite3_errmsg(m_db) : "sqlite_open returned null";
    103         LOG_ERROR("SQLite database failed to load from %s\nCause - %s", filename.ascii().data(),
    104             m_openErrorMessage.data());
    105         sqlite3_close(m_db);
    106         m_db = 0;
    107         return false;
     96    {
     97        std::lock_guard<Lock> lock(isDatabaseOpeningForbiddenMutex);
     98        if (isDatabaseOpeningForbidden) {
     99            m_openErrorMessage = "opening database is forbidden";
     100            return false;
     101        }
     102
     103        int flags = SQLITE_OPEN_AUTOPROXY;
     104        switch (openMode) {
     105        case OpenMode::ReadOnly:
     106            flags |= SQLITE_OPEN_READONLY;
     107            break;
     108        case OpenMode::ReadWrite:
     109            flags |= SQLITE_OPEN_READWRITE;
     110            break;
     111        case OpenMode::ReadWriteCreate:
     112            flags |= SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
     113            break;
     114        }
     115
     116        m_openError = sqlite3_open_v2(FileSystem::fileSystemRepresentation(filename).data(), &m_db, flags, nullptr);
     117        if (m_openError != SQLITE_OK) {
     118            m_openErrorMessage = m_db ? sqlite3_errmsg(m_db) : "sqlite_open returned null";
     119            LOG_ERROR("SQLite database failed to load from %s\nCause - %s", filename.ascii().data(),
     120                m_openErrorMessage.data());
     121            sqlite3_close(m_db);
     122            m_db = 0;
     123            return false;
     124        }
    108125    }
    109126
  • trunk/Source/WebCore/platform/sql/SQLiteDatabase.h

    r242983 r243939  
    139139#endif
    140140
     141    WEBCORE_EXPORT static void setIsDatabaseOpeningForbidden(bool);
     142
    141143private:
    142144    static int authorizerFunction(void*, int, const char*, const char*, const char*, const char*);
  • trunk/Source/WebCore/platform/sql/SQLiteDatabaseTracker.cpp

    r230303 r243939  
    4141void setClient(SQLiteDatabaseTrackerClient* client)
    4242{
    43     ASSERT(client);
    44     ASSERT(!s_staticSQLiteDatabaseTrackerClient || s_staticSQLiteDatabaseTrackerClient == client);
     43    std::lock_guard<Lock> lock(transactionInProgressMutex);
    4544    s_staticSQLiteDatabaseTrackerClient = client;
    4645}
     
    4847void incrementTransactionInProgressCount()
    4948{
     49    std::lock_guard<Lock> lock(transactionInProgressMutex);
    5050    if (!s_staticSQLiteDatabaseTrackerClient)
    5151        return;
    52 
    53     std::lock_guard<Lock> lock(transactionInProgressMutex);
    5452
    5553    s_transactionInProgressCounter++;
     
    6058void decrementTransactionInProgressCount()
    6159{
     60    std::lock_guard<Lock> lock(transactionInProgressMutex);
    6261    if (!s_staticSQLiteDatabaseTrackerClient)
    6362        return;
    64 
    65     std::lock_guard<Lock> lock(transactionInProgressMutex);
    6663
    6764    ASSERT(s_transactionInProgressCounter);
     
    7572bool hasTransactionInProgress()
    7673{
     74    std::lock_guard<Lock> lock(transactionInProgressMutex);
    7775    return !s_staticSQLiteDatabaseTrackerClient || s_transactionInProgressCounter > 0;
    7876}
  • trunk/Source/WebKit/ChangeLog

    r243934 r243939  
     12019-04-05  Sihui Liu  <sihui_liu@apple.com>
     2
     3        [iOS] Web process gets suspended while holding locked database files
     4        https://bugs.webkit.org/show_bug.cgi?id=196519
     5        <rdar://problem/49531797>
     6
     7        Reviewed by Chris Dumez.
     8
     9        * Shared/WebSQLiteDatabaseTracker.cpp:
     10        (WebKit::WebSQLiteDatabaseTracker::~WebSQLiteDatabaseTracker):
     11        * Shared/WebSQLiteDatabaseTracker.h:
     12        * WebProcess/WebProcess.cpp:
     13        (WebKit::m_webSQLiteDatabaseTracker):
     14        (WebKit::WebProcess::actualPrepareToSuspend):
     15        (WebKit::WebProcess::processWillSuspendImminently):
     16        (WebKit::WebProcess::cancelPrepareToSuspend):
     17        (WebKit::WebProcess::processDidResume):
     18        * WebProcess/WebProcess.h:
     19
    1202019-04-05  Commit Queue  <commit-queue@webkit.org>
    221
  • trunk/Source/WebKit/Shared/WebSQLiteDatabaseTracker.cpp

    r242230 r243939  
    5353}
    5454
     55WebSQLiteDatabaseTracker::~WebSQLiteDatabaseTracker()
     56{
     57    ASSERT(RunLoop::isMain());
     58    SQLiteDatabaseTracker::setClient(nullptr);
     59
     60    if (m_hysteresis.state() == PAL::HysteresisState::Started)
     61        hysteresisUpdated(PAL::HysteresisState::Stopped);
     62}
     63
    5564void WebSQLiteDatabaseTracker::willBeginFirstTransaction()
    5665{
  • trunk/Source/WebKit/Shared/WebSQLiteDatabaseTracker.h

    r242230 r243939  
    4141    explicit WebSQLiteDatabaseTracker(NetworkProcess&);
    4242
     43    ~WebSQLiteDatabaseTracker();
     44
    4345    // WebCore::SQLiteDatabaseTrackerClient
    4446    void willBeginFirstTransaction() override;
  • trunk/Source/WebKit/WebProcess/WebProcess.cpp

    r243671 r243939  
    138138#endif
    139139
     140#if PLATFORM(IOS_FAMILY)
     141#include "WebSQLiteDatabaseTracker.h"
     142#endif
     143
    140144#if ENABLE(SEC_ITEM_SHIM)
    141145#include "SecItemShim.h"
     
    185189    , m_nonVisibleProcessCleanupTimer(*this, &WebProcess::nonVisibleProcessCleanupTimerFired)
    186190#if PLATFORM(IOS_FAMILY)
    187     , m_webSQLiteDatabaseTracker(*this)
     191    , m_webSQLiteDatabaseTracker(std::make_unique<WebSQLiteDatabaseTracker>(*this))
    188192#endif
    189193{
     
    14621466
    14631467#if PLATFORM(IOS_FAMILY)
     1468    m_webSQLiteDatabaseTracker = nullptr;
     1469    SQLiteDatabase::setIsDatabaseOpeningForbidden(true);
     1470    DatabaseTracker::singleton().closeAllDatabases(CurrentQueryBehavior::Interrupt);
    14641471    accessibilityProcessSuspendedNotification(true);
    14651472    updateFreezerStatus();
     
    14901497
    14911498    RELEASE_LOG(ProcessSuspension, "%p - WebProcess::processWillSuspendImminently()", this);
    1492     DatabaseTracker::singleton().closeAllDatabases(CurrentQueryBehavior::Interrupt);
    14931499    actualPrepareToSuspend(ShouldAcknowledgeWhenReadyToSuspend::No);
    14941500    completionHandler(true);
     
    15071513
    15081514#if PLATFORM(IOS_FAMILY)
     1515    m_webSQLiteDatabaseTracker = std::make_unique<WebSQLiteDatabaseTracker>(*this);
     1516    SQLiteDatabase::setIsDatabaseOpeningForbidden(false);
    15091517    accessibilityProcessSuspendedNotification(false);
    15101518#endif
     
    15781586   
    15791587#if PLATFORM(IOS_FAMILY)
     1588    m_webSQLiteDatabaseTracker = std::make_unique<WebSQLiteDatabaseTracker>(*this);
     1589    SQLiteDatabase::setIsDatabaseOpeningForbidden(false);
    15801590    accessibilityProcessSuspendedNotification(false);
    15811591#endif
  • trunk/Source/WebKit/WebProcess/WebProcess.h

    r243395 r243939  
    5858#endif
    5959
    60 #if PLATFORM(IOS_FAMILY)
    61 #include "WebSQLiteDatabaseTracker.h"
    62 #endif
    63 
    6460namespace API {
    6561class Object;
     
    113109struct WebPageGroupData;
    114110struct WebPreferencesStore;
     111class WebSQLiteDatabaseTracker;
    115112struct WebsiteData;
    116113struct WebsiteDataStoreParameters;
     
    500497
    501498#if PLATFORM(IOS_FAMILY)
    502     WebSQLiteDatabaseTracker m_webSQLiteDatabaseTracker;
     499    std::unique_ptr<WebSQLiteDatabaseTracker> m_webSQLiteDatabaseTracker;
    503500#endif
    504501
Note: See TracChangeset for help on using the changeset viewer.