Changeset 184105 in webkit


Ignore:
Timestamp:
May 11, 2015 10:27:13 AM (9 years ago)
Author:
dbates@webkit.org
Message:

[iOS] Close all open databases in expiration handler of process assertion
https://bugs.webkit.org/show_bug.cgi?id=144661
<rdar://problem/20845052>

Reviewed by Darin Adler.

Source/WebCore:

Expose functionality in WebCore to close all open databases. Closing a SQLite database
will interrupt any in-progress database transactions.

  • Modules/webdatabase/AbstractDatabaseServer.h:
  • Modules/webdatabase/DatabaseManager.cpp:

(WebCore::DatabaseManager::closeAllDatabases): Added; turns around and calls DatabaseServer::closeAllDatabases().

  • Modules/webdatabase/DatabaseManager.h: Export DatabaseManager::closeAllDatabases() so that

we can call in from WebKit2.

  • Modules/webdatabase/DatabaseServer.cpp:

(WebCore::DatabaseServer::closeAllDatabases): Added; turns around and calls DatabaseTracker::closeAllDatabases().

  • Modules/webdatabase/DatabaseServer.h:
  • Modules/webdatabase/DatabaseTracker.cpp:

(WebCore::DatabaseTracker::closeAllDatabases): Added; closes all open databases.

  • Modules/webdatabase/DatabaseTracker.h: Export DatabaseTracker::closeAllDatabases() so that

we can call in from Legacy WebKit.

Source/WebKit/mac:

For Legacy WebKit, close all open databases when the process assertion expiration
handler is called.

  • Storage/WebDatabaseManager.mm:

(+[WebDatabaseManager startBackgroundTask]): Call DatabaseTracker::tracker().closeAllDatabases()
in the expiration handler to close all open databases. As a side effect of closing
a database all in-progress database transactions are interrupted.

Source/WebKit2:

For WebKit2, close all open databases when the process assertion expiration
handler is called.

When the process assertion expiration handler is called we dispatch a synchronous
message called ProcessWillSuspendImminently to the {Web, Network} processes to inform
them that they will be suspended imminently. The {Web, Network} process will always
service this message regardless if they were waiting for another message. In the
WebProcess, we will close all open databases among other tasks upon receiving this
message. In the NetworkProcess, we will purge some data from memory.

  • NetworkProcess/NetworkProcess.cpp:

(WebKit::NetworkProcess::didReceiveSyncMessage): Modified to call NetworkProcess::didReceiveSyncNetworkProcessMessage()
to process the synchronous ProcessWillSuspendImminently message.
(WebKit::NetworkProcess::processWillSuspendImminently): Added; free some memory.

  • NetworkProcess/NetworkProcess.h:
  • NetworkProcess/NetworkProcess.messages.in: Added synchronous message ProcessWillSuspendImminently.
  • Shared/ChildProcessProxy.h:

(WebKit::ChildProcessProxy::sendSync): Added parameter sendSyncFlags so that we can send
a sync message with flag IPC::InterruptWaitingIfSyncMessageArrives to cause the {Web, Network}Process
to process the message regardless of whether it is waiting for another message.

  • UIProcess/Network/NetworkProcessProxy.cpp:

(WebKit::NetworkProcessProxy::sendProcessWillSuspendImminently): Added. Sends the message
ProcessWillSuspendImminently to the NetworkProcess.

  • UIProcess/Network/NetworkProcessProxy.h:
  • UIProcess/ProcessAssertion.cpp:

(WebKit::ProcessAndUIAssertion::setClient): Added.

  • UIProcess/ProcessAssertion.h: Added abstract class ProcessAssertionClient.

(WebKit::ProcessAssertionClient::~ProcessAssertionClient): Added.
(WebKit::ProcessAssertion::setClient): Added.
(WebKit::ProcessAssertion::client): Added.

  • UIProcess/ProcessThrottler.cpp:

(WebKit::ProcessThrottler::didConnectToProcess):
(WebKit::ProcessThrottler::assertionWillExpireImminently): Added; implements the ProcessAssertionClient
interface. Notify the process throttler clients that the assertion is near expiration.

  • UIProcess/ProcessThrottler.h:
  • UIProcess/ProcessThrottlerClient.h: Added
  • UIProcess/WebProcessProxy.cpp:

(WebKit::WebProcessProxy::sendProcessWillSuspendImminently): Added. Sends the message
ProcessWillSuspendImminently to the WebProcess.

  • UIProcess/WebProcessProxy.h:
  • UIProcess/ios/ProcessAssertionIOS.mm:

(-[WKProcessAssertionBackgroundTaskManager addClient:]): Added.
(-[WKProcessAssertionBackgroundTaskManager removeClient:]): Added.
(-[WKProcessAssertionBackgroundTaskManager _updateBackgroundTask]): Modified expiration handler
to notify ProcessAssertionClient clients that the assertion is near expiration.
(WebKit::ProcessAssertion::~ProcessAssertion): Remove the client on destruction.
(WebKit::ProcessAndUIAssertion::setClient): Added.

  • WebProcess/WebCoreSupport/WebDatabaseManager.cpp:

(WebKit::WebDatabaseManager::closeAllDatabases): Added; turns around and calls DatabaseManager::closeAllDatabases().

  • WebProcess/WebCoreSupport/WebDatabaseManager.h:
  • WebProcess/WebProcess.cpp:

(WebKit::WebProcess::didReceiveSyncMessage): Call WebProcess::didReceiveSyncWebProcessMessage() to process
the synchronous ProcessWillSuspendImminently message. Removed logging for an unhandled synchronous message
since WebProcess::didReceiveSyncWebProcessMessage() will ASSERT_NOT_REACHED() for such a message.
(WebKit::WebProcess::prepareToSuspend): Extracted code from WebProcess::processWillSuspend() so that it can
be used from both WebProcess::processWillSuspend() and WebProcess::processWillSuspendImminently(). And modified
it to conditionally dispatch a ProcessReadyToSuspend message to the WebProcessProxy. We only want to dispatch
such a message as part of a coordinated suspension by the ProcessThrottler. That is, we do not want to dispatch
the ProcessReadyToSuspend message when the background assertion is near expiration (i.e. WebProcess::processWillSuspendImminently()
is called).
(WebKit::WebProcess::processWillSuspendImminently): Added. Suspend all open databases among other tasks.
(WebKit::WebProcess::processWillSuspend): Implemented in terms of WebProcess::prepareToSuspend().
(WebKit::WebProcess::processSuspensionCleanupTimerFired): Modified to conditionally dispatch a ProcessReadyToSuspend
message to the WebProcessProxy.
(WebKit::WebProcess::processDidResume): Stop the suspension cleanup timer, which may be active if the WebProcess
did not mark all its graphics layers as volatile before process suspension.

  • WebProcess/WebProcess.h:
  • WebProcess/WebProcess.messages.in: Added synchronous message ProcessWillSuspendImminently.
Location:
trunk/Source
Files:
30 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r184104 r184105  
     12015-05-11  Daniel Bates  <dabates@apple.com>
     2
     3        [iOS] Close all open databases in expiration handler of process assertion
     4        https://bugs.webkit.org/show_bug.cgi?id=144661
     5        <rdar://problem/20845052>
     6
     7        Reviewed by Darin Adler.
     8
     9        Expose functionality in WebCore to close all open databases. Closing a SQLite database
     10        will interrupt any in-progress database transactions.
     11
     12        * Modules/webdatabase/AbstractDatabaseServer.h:
     13        * Modules/webdatabase/DatabaseManager.cpp:
     14        (WebCore::DatabaseManager::closeAllDatabases): Added; turns around and calls DatabaseServer::closeAllDatabases().
     15        * Modules/webdatabase/DatabaseManager.h: Export DatabaseManager::closeAllDatabases() so that
     16        we can call in from WebKit2.
     17        * Modules/webdatabase/DatabaseServer.cpp:
     18        (WebCore::DatabaseServer::closeAllDatabases): Added; turns around and calls DatabaseTracker::closeAllDatabases().
     19        * Modules/webdatabase/DatabaseServer.h:
     20        * Modules/webdatabase/DatabaseTracker.cpp:
     21        (WebCore::DatabaseTracker::closeAllDatabases): Added; closes all open databases.
     22        * Modules/webdatabase/DatabaseTracker.h: Export DatabaseTracker::closeAllDatabases() so that
     23        we can call in from Legacy WebKit.
     24
    1252015-05-11  Antti Koivisto  <antti@apple.com>
    226
  • trunk/Source/WebCore/Modules/webdatabase/AbstractDatabaseServer.h

    r183909 r184105  
    5858    virtual PassRefPtr<DatabaseBackendBase> openDatabase(RefPtr<DatabaseContext>&, const String& name, const String& expectedVersion, const String& displayName, unsigned long estimatedSize, bool setVersionInNewDatabase, DatabaseError&, String& errorMessage, OpenAttempt = FirstTryToOpenDatabase) = 0;
    5959
     60    virtual void closeAllDatabases() = 0;
     61
    6062    virtual bool hasEntryForOrigin(SecurityOrigin*) = 0;
    6163    virtual void origins(Vector<RefPtr<SecurityOrigin>>& result) = 0;
  • trunk/Source/WebCore/Modules/webdatabase/DatabaseManager.cpp

    r183909 r184105  
    403403}
    404404
     405void DatabaseManager::closeAllDatabases()
     406{
     407    m_server->closeAllDatabases();
     408}
     409
    405410void DatabaseManager::interruptAllDatabasesForContext(ScriptExecutionContext* context)
    406411{
  • trunk/Source/WebCore/Modules/webdatabase/DatabaseManager.h

    r183909 r184105  
    8686
    8787    WEBCORE_EXPORT bool hasOpenDatabases(ScriptExecutionContext*);
     88
     89    WEBCORE_EXPORT void closeAllDatabases();
     90
    8891    void stopDatabases(ScriptExecutionContext*, DatabaseTaskSynchronizer*);
    8992
  • trunk/Source/WebCore/Modules/webdatabase/DatabaseServer.cpp

    r183909 r184105  
    118118}
    119119
     120void DatabaseServer::closeAllDatabases()
     121{
     122    DatabaseTracker::tracker().closeAllDatabases();
     123}
     124
    120125void DatabaseServer::interruptAllDatabasesForContext(const DatabaseContext* context)
    121126{
  • trunk/Source/WebCore/Modules/webdatabase/DatabaseServer.h

    r183909 r184105  
    4747    virtual PassRefPtr<DatabaseBackendBase> openDatabase(RefPtr<DatabaseContext>&, const String& name, const String& expectedVersion, const String& displayName, unsigned long estimatedSize, bool setVersionInNewDatabase, DatabaseError&, String& errorMessage, OpenAttempt);
    4848
     49    void closeAllDatabases() override;
     50
    4951    virtual bool hasEntryForOrigin(SecurityOrigin*);
    5052    virtual void origins(Vector<RefPtr<SecurityOrigin>>& result);
  • trunk/Source/WebCore/Modules/webdatabase/DatabaseTracker.cpp

    r182365 r184105  
    305305        maxSize = databaseFileSize;
    306306    return maxSize;
     307}
     308
     309void DatabaseTracker::closeAllDatabases()
     310{
     311    Vector<Ref<Database>> openDatabases;
     312    {
     313        MutexLocker openDatabaseMapLock(m_openDatabaseMapGuard);
     314        if (!m_openDatabaseMap)
     315            return;
     316        for (auto& nameMap : m_openDatabaseMap->values()) {
     317            for (auto& set : nameMap->values()) {
     318                for (auto& database : *set)
     319                    openDatabases.append(*database);
     320            }
     321        }
     322    }
     323    for (auto& database : openDatabases)
     324        database->close();
    307325}
    308326
  • trunk/Source/WebCore/Modules/webdatabase/DatabaseTracker.h

    r181837 r184105  
    7474
    7575    unsigned long long getMaxSizeForDatabase(const Database*);
     76
     77    WEBCORE_EXPORT void closeAllDatabases();
    7678
    7779    void interruptAllDatabasesForContext(const DatabaseContext*);
  • trunk/Source/WebKit/mac/ChangeLog

    r184056 r184105  
     12015-05-11  Daniel Bates  <dabates@apple.com>
     2
     3        [iOS] Close all open databases in expiration handler of process assertion
     4        https://bugs.webkit.org/show_bug.cgi?id=144661
     5        <rdar://problem/20845052>
     6
     7        Reviewed by Darin Adler.
     8
     9        For Legacy WebKit, close all open databases when the process assertion expiration
     10        handler is called.
     11
     12        * Storage/WebDatabaseManager.mm:
     13        (+[WebDatabaseManager startBackgroundTask]): Call DatabaseTracker::tracker().closeAllDatabases()
     14        in the expiration handler to close all open databases. As a side effect of closing
     15        a database all in-progress database transactions are interrupted.
     16
    1172015-05-10  Sungmann Cho  <sungmann.cho@navercorp.com>
    218
  • trunk/Source/WebKit/mac/Storage/WebDatabaseManager.mm

    r180704 r184105  
    268268        return;
    269269   
    270     setTransactionBackgroundTaskIdentifier(startBackgroundTask(^ { [WebDatabaseManager endBackgroundTask]; }));
     270    setTransactionBackgroundTaskIdentifier(startBackgroundTask(^ {
     271        DatabaseTracker::tracker().closeAllDatabases();
     272        [WebDatabaseManager endBackgroundTask];
     273    }));
    271274}
    272275
  • trunk/Source/WebKit2/ChangeLog

    r184066 r184105  
     12015-05-11  Daniel Bates  <dabates@apple.com>
     2
     3        [iOS] Close all open databases in expiration handler of process assertion
     4        https://bugs.webkit.org/show_bug.cgi?id=144661
     5        <rdar://problem/20845052>
     6
     7        Reviewed by Darin Adler.
     8
     9        For WebKit2, close all open databases when the process assertion expiration
     10        handler is called.
     11
     12        When the process assertion expiration handler is called we dispatch a synchronous
     13        message called ProcessWillSuspendImminently to the {Web, Network} processes to inform
     14        them that they will be suspended imminently. The {Web, Network} process will always
     15        service this message regardless if they were waiting for another message. In the
     16        WebProcess, we will close all open databases among other tasks upon receiving this
     17        message. In the NetworkProcess, we will purge some data from memory.
     18
     19        * NetworkProcess/NetworkProcess.cpp:
     20        (WebKit::NetworkProcess::didReceiveSyncMessage): Modified to call NetworkProcess::didReceiveSyncNetworkProcessMessage()
     21        to process the synchronous ProcessWillSuspendImminently message.
     22        (WebKit::NetworkProcess::processWillSuspendImminently): Added; free some memory.
     23        * NetworkProcess/NetworkProcess.h:
     24        * NetworkProcess/NetworkProcess.messages.in: Added synchronous message ProcessWillSuspendImminently.
     25        * Shared/ChildProcessProxy.h:
     26        (WebKit::ChildProcessProxy::sendSync): Added parameter sendSyncFlags so that we can send
     27        a sync message with flag IPC::InterruptWaitingIfSyncMessageArrives to cause the {Web, Network}Process
     28        to process the message regardless of whether it is waiting for another message.
     29        * UIProcess/Network/NetworkProcessProxy.cpp:
     30        (WebKit::NetworkProcessProxy::sendProcessWillSuspendImminently): Added. Sends the message
     31        ProcessWillSuspendImminently to the NetworkProcess.
     32        * UIProcess/Network/NetworkProcessProxy.h:
     33        * UIProcess/ProcessAssertion.cpp:
     34        (WebKit::ProcessAndUIAssertion::setClient): Added.
     35        * UIProcess/ProcessAssertion.h: Added abstract class ProcessAssertionClient.
     36        (WebKit::ProcessAssertionClient::~ProcessAssertionClient): Added.
     37        (WebKit::ProcessAssertion::setClient): Added.
     38        (WebKit::ProcessAssertion::client): Added.
     39        * UIProcess/ProcessThrottler.cpp:
     40        (WebKit::ProcessThrottler::didConnectToProcess):
     41        (WebKit::ProcessThrottler::assertionWillExpireImminently): Added; implements the ProcessAssertionClient
     42        interface. Notify the process throttler clients that the assertion is near expiration.
     43        * UIProcess/ProcessThrottler.h:
     44        * UIProcess/ProcessThrottlerClient.h: Added
     45        * UIProcess/WebProcessProxy.cpp:
     46        (WebKit::WebProcessProxy::sendProcessWillSuspendImminently): Added. Sends the message
     47        ProcessWillSuspendImminently to the WebProcess.
     48        * UIProcess/WebProcessProxy.h:
     49        * UIProcess/ios/ProcessAssertionIOS.mm:
     50        (-[WKProcessAssertionBackgroundTaskManager addClient:]): Added.
     51        (-[WKProcessAssertionBackgroundTaskManager removeClient:]): Added.
     52        (-[WKProcessAssertionBackgroundTaskManager _updateBackgroundTask]): Modified expiration handler
     53        to notify ProcessAssertionClient clients that the assertion is near expiration.
     54        (WebKit::ProcessAssertion::~ProcessAssertion): Remove the client on destruction.
     55        (WebKit::ProcessAndUIAssertion::setClient): Added.
     56        * WebProcess/WebCoreSupport/WebDatabaseManager.cpp:
     57        (WebKit::WebDatabaseManager::closeAllDatabases): Added; turns around and calls DatabaseManager::closeAllDatabases().
     58        * WebProcess/WebCoreSupport/WebDatabaseManager.h:
     59        * WebProcess/WebProcess.cpp:
     60        (WebKit::WebProcess::didReceiveSyncMessage): Call WebProcess::didReceiveSyncWebProcessMessage() to process
     61        the synchronous ProcessWillSuspendImminently message. Removed logging for an unhandled synchronous message
     62        since WebProcess::didReceiveSyncWebProcessMessage() will ASSERT_NOT_REACHED() for such a message.
     63        (WebKit::WebProcess::prepareToSuspend): Extracted code from WebProcess::processWillSuspend() so that it can
     64        be used from both WebProcess::processWillSuspend() and WebProcess::processWillSuspendImminently(). And modified
     65        it to conditionally dispatch a ProcessReadyToSuspend message to the WebProcessProxy. We only want to dispatch
     66        such a message as part of a coordinated suspension by the ProcessThrottler. That is, we do not want to dispatch
     67        the ProcessReadyToSuspend message when the background assertion is near expiration (i.e. WebProcess::processWillSuspendImminently()
     68        is called).
     69        (WebKit::WebProcess::processWillSuspendImminently): Added. Suspend all open databases among other tasks.
     70        (WebKit::WebProcess::processWillSuspend): Implemented in terms of WebProcess::prepareToSuspend().
     71        (WebKit::WebProcess::processSuspensionCleanupTimerFired): Modified to conditionally dispatch a ProcessReadyToSuspend
     72        message to the WebProcessProxy.
     73        (WebKit::WebProcess::processDidResume): Stop the suspension cleanup timer, which may be active if the WebProcess
     74        did not mark all its graphics layers as volatile before process suspension.
     75        * WebProcess/WebProcess.h:
     76        * WebProcess/WebProcess.messages.in: Added synchronous message ProcessWillSuspendImminently.
     77
    1782015-05-10  Gyuyoung Kim  <gyuyoung.kim@webkit.org>
    279
  • trunk/Source/WebKit2/NetworkProcess/NetworkProcess.cpp

    r183737 r184105  
    133133void NetworkProcess::didReceiveSyncMessage(IPC::Connection& connection, IPC::MessageDecoder& decoder, std::unique_ptr<IPC::MessageEncoder>& replyEncoder)
    134134{
    135     messageReceiverMap().dispatchSyncMessage(connection, decoder, replyEncoder);
     135    if (messageReceiverMap().dispatchSyncMessage(connection, decoder, replyEncoder))
     136        return;
     137
     138    didReceiveSyncNetworkProcessMessage(connection, decoder, replyEncoder);
    136139}
    137140
     
    506509}
    507510
     511void NetworkProcess::processWillSuspendImminently(bool& handled)
     512{
     513    lowMemoryHandler(true);
     514    handled = true;
     515}
     516
    508517void NetworkProcess::processWillSuspend()
    509518{
  • trunk/Source/WebKit2/NetworkProcess/NetworkProcess.h

    r183737 r184105  
    7979    bool canHandleHTTPSServerTrustEvaluation() const { return m_canHandleHTTPSServerTrustEvaluation; }
    8080
     81    void processWillSuspendImminently(bool& handled);
    8182    void processWillSuspend();
    8283    void cancelProcessWillSuspend();
     
    123124    // Message Handlers
    124125    void didReceiveNetworkProcessMessage(IPC::Connection&, IPC::MessageDecoder&);
     126    void didReceiveSyncNetworkProcessMessage(IPC::Connection&, IPC::MessageDecoder&, std::unique_ptr<IPC::MessageEncoder>&);
    125127    void initializeNetworkProcess(const NetworkProcessCreationParameters&);
    126128    void createNetworkConnectionToWebProcess();
  • trunk/Source/WebKit2/NetworkProcess/NetworkProcess.messages.in

    r182194 r184105  
    5959    SetCacheModel(uint32_t cacheModel);
    6060
     61    ProcessWillSuspendImminently() -> (bool handled)
    6162    ProcessWillSuspend()
    6263    CancelProcessWillSuspend()
  • trunk/Source/WebKit2/Shared/ChildProcessProxy.h

    r178598 r184105  
    4949
    5050    template<typename T> bool send(T&& message, uint64_t destinationID, unsigned messageSendFlags = 0);
    51     template<typename T> bool sendSync(T&& message, typename T::Reply&&, uint64_t destinationID, std::chrono::milliseconds timeout = std::chrono::seconds(1));
     51    template<typename T> bool sendSync(T&& message, typename T::Reply&&, uint64_t destinationID, std::chrono::milliseconds timeout = std::chrono::seconds(1), unsigned sendSyncFlags = 0);
    5252   
    5353    IPC::Connection* connection() const
     
    106106
    107107template<typename U>
    108 bool ChildProcessProxy::sendSync(U&& message, typename U::Reply&& reply, uint64_t destinationID, std::chrono::milliseconds timeout)
     108bool ChildProcessProxy::sendSync(U&& message, typename U::Reply&& reply, uint64_t destinationID, std::chrono::milliseconds timeout, unsigned sendSyncFlags)
    109109{
    110110    COMPILE_ASSERT(U::isSync, SyncMessageExpected);
     
    113113        return false;
    114114
    115     return connection()->sendSync(std::forward<U>(message), WTF::move(reply), destinationID, timeout);
     115    return connection()->sendSync(std::forward<U>(message), WTF::move(reply), destinationID, timeout, sendSyncFlags);
    116116}
    117117
  • trunk/Source/WebKit2/UIProcess/Network/NetworkProcessProxy.cpp

    r182323 r184105  
    314314}
    315315
     316void NetworkProcessProxy::sendProcessWillSuspendImminently()
     317{
     318    if (!canSendMessage())
     319        return;
     320
     321    bool handled = false;
     322    sendSync(Messages::NetworkProcess::ProcessWillSuspendImminently(), Messages::NetworkProcess::ProcessWillSuspendImminently::Reply(handled),
     323        0, std::chrono::seconds(1), IPC::InterruptWaitingIfSyncMessageArrives);
     324}
     325   
    316326void NetworkProcessProxy::sendProcessWillSuspend()
    317327{
  • trunk/Source/WebKit2/UIProcess/Network/NetworkProcessProxy.h

    r182323 r184105  
    7070#endif
    7171
     72    void sendProcessWillSuspendImminently() override;
    7273    void sendProcessWillSuspend() override;
    7374    void sendCancelProcessWillSuspend() override;
  • trunk/Source/WebKit2/UIProcess/ProcessAssertion.cpp

    r173623 r184105  
    4747    m_assertionState = assertionState;
    4848}
    49    
     49
    5050ProcessAndUIAssertion::ProcessAndUIAssertion(pid_t pid, AssertionState assertionState)
    5151    : ProcessAssertion(pid, assertionState)
     
    6161    ProcessAssertion::setState(assertionState);
    6262}
    63    
     63
     64void ProcessAndUIAssertion::setClient(ProcessAssertionClient& client)
     65{
     66    ProcessAssertion::setClient(client);
     67}
     68
    6469}
    6570
  • trunk/Source/WebKit2/UIProcess/ProcessAssertion.h

    r173623 r184105  
    4040};
    4141
     42class ProcessAssertionClient {
     43public:
     44    virtual ~ProcessAssertionClient() { };
     45    virtual void assertionWillExpireImminently() = 0;
     46};
     47
    4248class ProcessAssertion {
    4349public:
     
    4551    ~ProcessAssertion();
    4652
     53    void setClient(ProcessAssertionClient& client) { m_client = &client; }
     54    ProcessAssertionClient* client() { return m_client; }
     55
    4756    AssertionState state() const { return m_assertionState; }
    48    
    4957    void setState(AssertionState);
    50    
     58
    5159private:
    5260#if PLATFORM(IOS) && !PLATFORM(IOS_SIMULATOR)
     
    5462#endif
    5563    AssertionState m_assertionState;
     64    ProcessAssertionClient* m_client { nullptr };
    5665};
    5766   
     
    6069    ProcessAndUIAssertion(pid_t, AssertionState);
    6170    ~ProcessAndUIAssertion();
    62    
     71
     72    void setClient(ProcessAssertionClient&);
     73
    6374    void setState(AssertionState);
    6475};
  • trunk/Source/WebKit2/UIProcess/ProcessThrottler.cpp

    r182194 r184105  
    8989    m_suspendTimer.stop();
    9090    m_assertion = std::make_unique<ProcessAndUIAssertion>(pid, assertionState());
     91    m_assertion->setClient(*this);
    9192}
    9293   
     
    110111}
    111112
     113void ProcessThrottler::assertionWillExpireImminently()
     114{
     115    m_process->sendProcessWillSuspendImminently();
    112116}
     117
     118}
  • trunk/Source/WebKit2/UIProcess/ProcessThrottler.h

    r182194 r184105  
    4242class ProcessThrottlerClient;
    4343
    44 class ProcessThrottler {
     44class ProcessThrottler : private ProcessAssertionClient {
    4545public:
    4646    enum ForegroundActivityTokenType { };
     
    5757    void processReadyToSuspend();
    5858    void didCancelProcessSuspension();
    59    
     59
    6060private:
    6161    AssertionState assertionState();
     
    6363    void updateAssertionNow();
    6464    void suspendTimerFired();
    65    
     65
     66    // ProcessAssertionClient
     67    void assertionWillExpireImminently() override;
     68
    6669    ProcessThrottlerClient* m_process;
    6770    std::unique_ptr<ProcessAndUIAssertion> m_assertion;
  • trunk/Source/WebKit2/UIProcess/ProcessThrottlerClient.h

    r182194 r184105  
    3333    virtual ~ProcessThrottlerClient() { }
    3434
     35    virtual void sendProcessWillSuspendImminently() = 0;
    3536    virtual void sendProcessWillSuspend() = 0;
    3637    virtual void sendCancelProcessWillSuspend() = 0;
  • trunk/Source/WebKit2/UIProcess/WebProcessProxy.cpp

    r184054 r184105  
    890890}
    891891
     892void WebProcessProxy::sendProcessWillSuspendImminently()
     893{
     894    if (!canSendMessage())
     895        return;
     896
     897    bool handled = false;
     898    sendSync(Messages::WebProcess::ProcessWillSuspendImminently(), Messages::WebProcess::ProcessWillSuspendImminently::Reply(handled),
     899        0, std::chrono::seconds(1), IPC::InterruptWaitingIfSyncMessageArrives);
     900}
     901
    892902void WebProcessProxy::sendProcessWillSuspend()
    893903{
  • trunk/Source/WebKit2/UIProcess/WebProcessProxy.h

    r182610 r184105  
    144144    void windowServerConnectionStateChanged();
    145145
     146    void sendProcessWillSuspendImminently() override;
    146147    void sendProcessWillSuspend() override;
    147148    void processReadyToSuspend();
  • trunk/Source/WebKit2/UIProcess/ios/ProcessAssertionIOS.mm

    r178080 r184105  
    3131#import "BKSProcessAssertionSPI.h"
    3232#import <UIKit/UIApplication.h>
     33#import <wtf/HashSet.h>
     34#import <wtf/Vector.h>
    3335
    3436#if !PLATFORM(IOS_SIMULATOR)
     37
     38using WebKit::ProcessAssertionClient;
    3539
    3640@interface WKProcessAssertionBackgroundTaskManager : NSObject
     
    4044- (void)incrementNeedsToRunInBackgroundCount;
    4145- (void)decrementNeedsToRunInBackgroundCount;
     46
     47- (void)addClient:(ProcessAssertionClient&)client;
     48- (void)removeClient:(ProcessAssertionClient&)client;
    4249
    4350@end
     
    4855    BOOL _appIsBackground;
    4956    UIBackgroundTaskIdentifier _backgroundTask;
     57    HashSet<ProcessAssertionClient*> _clients;
    5058}
    5159
     
    8492}
    8593
     94- (void)addClient:(ProcessAssertionClient&)client
     95{
     96    _clients.add(&client);
     97}
     98
     99- (void)removeClient:(ProcessAssertionClient&)client
     100{
     101    _clients.remove(&client);
     102}
     103
    86104- (void)_updateBackgroundTask
    87105{
     
    91109        _backgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithName:@"com.apple.WebKit.ProcessAssertion" expirationHandler:^{
    92110            NSLog(@"Background task expired while holding WebKit ProcessAssertion.");
     111            Vector<ProcessAssertionClient*> clientsToNotify;
     112            copyToVector(_clients, clientsToNotify);
     113            for (auto* client : clientsToNotify)
     114                client->assertionWillExpireImminently();
    93115            [[UIApplication sharedApplication] endBackgroundTask:_backgroundTask];
    94116            _backgroundTask = UIBackgroundTaskInvalid;
     
    161183ProcessAssertion::~ProcessAssertion()
    162184{
     185    if (ProcessAssertionClient* client = this->client())
     186        [[WKProcessAssertionBackgroundTaskManager shared] removeClient:*client];
    163187    [m_assertion invalidate];
    164188}
     
    196220}
    197221
     222void ProcessAndUIAssertion::setClient(ProcessAssertionClient& newClient)
     223{
     224    [[WKProcessAssertionBackgroundTaskManager shared] addClient:newClient];
     225    if (ProcessAssertionClient* oldClient = this->client())
     226        [[WKProcessAssertionBackgroundTaskManager shared] removeClient:*oldClient];
     227    ProcessAssertion::setClient(newClient);
     228}
     229
    198230} // namespace WebKit
    199231
     
    230262}
    231263
     264void ProcessAndUIAssertion::setClient(ProcessAssertionClient& newClient)
     265{
     266    ProcessAssertion::setClient(newClient);
     267}
     268
    232269} // namespace WebKit
    233270
  • trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebDatabaseManager.cpp

    r183909 r184105  
    143143}
    144144
     145void WebDatabaseManager::closeAllDatabases() const
     146{
     147    DatabaseManager::singleton().closeAllDatabases();
     148}
     149
    145150void WebDatabaseManager::setQuotaForOrigin(const String& originIdentifier, unsigned long long quota) const
    146151{
  • trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebDatabaseManager.h

    r183909 r184105  
    4949    void setPauseAllDatabases(bool);
    5050
     51    void closeAllDatabases() const;
     52
    5153private:
    5254    // WebProcessSupplement
  • trunk/Source/WebKit2/WebProcess/WebProcess.cpp

    r182626 r184105  
    609609        return;
    610610
    611     LOG_ERROR("Unhandled synchronous web process message '%s:%s'", decoder.messageReceiverName().toString().data(), decoder.messageName().toString().data());
     611    didReceiveSyncWebProcessMessage(connection, decoder, replyEncoder);
    612612}
    613613
     
    12181218}
    12191219#endif
    1220    
    1221 void WebProcess::processWillSuspend()
     1220
     1221void WebProcess::prepareToSuspend(ShouldAcknowledgeWhenReadyToSuspend shouldAcknowledgeWhenReadyToSuspend)
    12221222{
    12231223    MemoryPressureHandler::singleton().releaseMemory(true);
    12241224    setAllLayerTreeStatesFrozen(true);
    12251225
    1226     if (!markAllLayersVolatileIfPossible())
    1227         m_processSuspensionCleanupTimer.startRepeating(std::chrono::milliseconds(20));
    1228     else
    1229         parentProcessConnection()->send(Messages::WebProcessProxy::ProcessReadyToSuspend(), 0);
     1226    if (markAllLayersVolatileIfPossible()) {
     1227        if (shouldAcknowledgeWhenReadyToSuspend == ShouldAcknowledgeWhenReadyToSuspend::Yes)
     1228            parentProcessConnection()->send(Messages::WebProcessProxy::ProcessReadyToSuspend(), 0);
     1229        return;
     1230    }
     1231    m_shouldAcknowledgeWhenReadyToSuspend = shouldAcknowledgeWhenReadyToSuspend;
     1232    m_processSuspensionCleanupTimer.startRepeating(std::chrono::milliseconds(20));
     1233}
     1234
     1235void WebProcess::processWillSuspendImminently(bool& handled)
     1236{
     1237    supplement<WebDatabaseManager>()->closeAllDatabases();
     1238    prepareToSuspend(ShouldAcknowledgeWhenReadyToSuspend::No);
     1239    handled = true;
     1240}
     1241
     1242void WebProcess::processWillSuspend()
     1243{
     1244    prepareToSuspend(ShouldAcknowledgeWhenReadyToSuspend::Yes);
    12301245}
    12311246
     
    12641279void WebProcess::processSuspensionCleanupTimerFired()
    12651280{
    1266     if (markAllLayersVolatileIfPossible()) {
    1267         m_processSuspensionCleanupTimer.stop();
     1281    if (!markAllLayersVolatileIfPossible())
     1282        return;
     1283    m_processSuspensionCleanupTimer.stop();
     1284    if (m_shouldAcknowledgeWhenReadyToSuspend == ShouldAcknowledgeWhenReadyToSuspend::Yes)
    12681285        parentProcessConnection()->send(Messages::WebProcessProxy::ProcessReadyToSuspend(), 0);
    1269     }
    12701286}
    12711287   
    12721288void WebProcess::processDidResume()
    12731289{
     1290    m_processSuspensionCleanupTimer.stop();
    12741291    setAllLayerTreeStatesFrozen(false);
    12751292}
  • trunk/Source/WebKit2/WebProcess/WebProcess.h

    r182437 r184105  
    185185#endif
    186186
     187    void processWillSuspendImminently(bool& handled);
    187188    void processWillSuspend();
    188189    void cancelProcessWillSuspend();
     
    283284    void setInjectedBundleParameter(const String& key, const IPC::DataReference&);
    284285
     286    enum class ShouldAcknowledgeWhenReadyToSuspend { No, Yes };
     287    void prepareToSuspend(ShouldAcknowledgeWhenReadyToSuspend);
     288
    285289    // ChildProcess
    286290    virtual void initializeProcess(const ChildProcessInitializationParameters&) override;
     
    308312    // Implemented in generated WebProcessMessageReceiver.cpp
    309313    void didReceiveWebProcessMessage(IPC::Connection&, IPC::MessageDecoder&);
     314    void didReceiveSyncWebProcessMessage(IPC::Connection&, IPC::MessageDecoder&, std::unique_ptr<IPC::MessageEncoder>&);
    310315
    311316    // WebOriginDataManagerSupplement
     
    382387    WebSQLiteDatabaseTracker m_webSQLiteDatabaseTracker;
    383388#endif
     389
     390    ShouldAcknowledgeWhenReadyToSuspend m_shouldAcknowledgeWhenReadyToSuspend;
    384391};
    385392
  • trunk/Source/WebKit2/WebProcess/WebProcess.messages.in

    r181562 r184105  
    101101#endif
    102102
     103    ProcessWillSuspendImminently() -> (bool handled)
    103104    ProcessWillSuspend()
    104105    CancelProcessWillSuspend()
Note: See TracChangeset for help on using the changeset viewer.