Title: [184105] trunk/Source
Revision
184105
Author
[email protected]
Date
2015-05-11 10:27:13 -0700 (Mon, 11 May 2015)

Log 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.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (184104 => 184105)


--- trunk/Source/WebCore/ChangeLog	2015-05-11 16:26:16 UTC (rev 184104)
+++ trunk/Source/WebCore/ChangeLog	2015-05-11 17:27:13 UTC (rev 184105)
@@ -1,3 +1,27 @@
+2015-05-11  Daniel Bates  <[email protected]>
+
+        [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.
+
+        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.
+
 2015-05-11  Antti Koivisto  <[email protected]>
 
         WebContent crash under com.apple.WebCore: WebCore::WebKitCSSResourceValue::isCSSValueNone const + 6

Modified: trunk/Source/WebCore/Modules/webdatabase/AbstractDatabaseServer.h (184104 => 184105)


--- trunk/Source/WebCore/Modules/webdatabase/AbstractDatabaseServer.h	2015-05-11 16:26:16 UTC (rev 184104)
+++ trunk/Source/WebCore/Modules/webdatabase/AbstractDatabaseServer.h	2015-05-11 17:27:13 UTC (rev 184105)
@@ -57,6 +57,8 @@
 
     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;
 
+    virtual void closeAllDatabases() = 0;
+
     virtual bool hasEntryForOrigin(SecurityOrigin*) = 0;
     virtual void origins(Vector<RefPtr<SecurityOrigin>>& result) = 0;
     virtual bool databaseNamesForOrigin(SecurityOrigin*, Vector<String>& result) = 0;

Modified: trunk/Source/WebCore/Modules/webdatabase/DatabaseManager.cpp (184104 => 184105)


--- trunk/Source/WebCore/Modules/webdatabase/DatabaseManager.cpp	2015-05-11 16:26:16 UTC (rev 184104)
+++ trunk/Source/WebCore/Modules/webdatabase/DatabaseManager.cpp	2015-05-11 17:27:13 UTC (rev 184105)
@@ -402,6 +402,11 @@
     m_server->setPauseAllDatabases(pauseAllDatabases);
 }
 
+void DatabaseManager::closeAllDatabases()
+{
+    m_server->closeAllDatabases();
+}
+
 void DatabaseManager::interruptAllDatabasesForContext(ScriptExecutionContext* context)
 {
     RefPtr<DatabaseContext> databaseContext = existingDatabaseContextFor(context);

Modified: trunk/Source/WebCore/Modules/webdatabase/DatabaseManager.h (184104 => 184105)


--- trunk/Source/WebCore/Modules/webdatabase/DatabaseManager.h	2015-05-11 16:26:16 UTC (rev 184104)
+++ trunk/Source/WebCore/Modules/webdatabase/DatabaseManager.h	2015-05-11 17:27:13 UTC (rev 184105)
@@ -85,6 +85,9 @@
     PassRefPtr<Database> openDatabase(ScriptExecutionContext*, const String& name, const String& expectedVersion, const String& displayName, unsigned long estimatedSize, PassRefPtr<DatabaseCallback>, DatabaseError&);
 
     WEBCORE_EXPORT bool hasOpenDatabases(ScriptExecutionContext*);
+
+    WEBCORE_EXPORT void closeAllDatabases();
+
     void stopDatabases(ScriptExecutionContext*, DatabaseTaskSynchronizer*);
 
     String fullPathForDatabase(SecurityOrigin*, const String& name, bool createIfDoesNotExist = true);

Modified: trunk/Source/WebCore/Modules/webdatabase/DatabaseServer.cpp (184104 => 184105)


--- trunk/Source/WebCore/Modules/webdatabase/DatabaseServer.cpp	2015-05-11 16:26:16 UTC (rev 184104)
+++ trunk/Source/WebCore/Modules/webdatabase/DatabaseServer.cpp	2015-05-11 17:27:13 UTC (rev 184105)
@@ -117,6 +117,11 @@
 #endif
 }
 
+void DatabaseServer::closeAllDatabases()
+{
+    DatabaseTracker::tracker().closeAllDatabases();
+}
+
 void DatabaseServer::interruptAllDatabasesForContext(const DatabaseContext* context)
 {
     DatabaseTracker::tracker().interruptAllDatabasesForContext(context);

Modified: trunk/Source/WebCore/Modules/webdatabase/DatabaseServer.h (184104 => 184105)


--- trunk/Source/WebCore/Modules/webdatabase/DatabaseServer.h	2015-05-11 16:26:16 UTC (rev 184104)
+++ trunk/Source/WebCore/Modules/webdatabase/DatabaseServer.h	2015-05-11 17:27:13 UTC (rev 184105)
@@ -46,6 +46,8 @@
 
     virtual PassRefPtr<DatabaseBackendBase> openDatabase(RefPtr<DatabaseContext>&, const String& name, const String& expectedVersion, const String& displayName, unsigned long estimatedSize, bool setVersionInNewDatabase, DatabaseError&, String& errorMessage, OpenAttempt);
 
+    void closeAllDatabases() override;
+
     virtual bool hasEntryForOrigin(SecurityOrigin*);
     virtual void origins(Vector<RefPtr<SecurityOrigin>>& result);
     virtual bool databaseNamesForOrigin(SecurityOrigin*, Vector<String>& result);

Modified: trunk/Source/WebCore/Modules/webdatabase/DatabaseTracker.cpp (184104 => 184105)


--- trunk/Source/WebCore/Modules/webdatabase/DatabaseTracker.cpp	2015-05-11 16:26:16 UTC (rev 184104)
+++ trunk/Source/WebCore/Modules/webdatabase/DatabaseTracker.cpp	2015-05-11 17:27:13 UTC (rev 184105)
@@ -306,6 +306,24 @@
     return maxSize;
 }
 
+void DatabaseTracker::closeAllDatabases()
+{
+    Vector<Ref<Database>> openDatabases;
+    {
+        MutexLocker openDatabaseMapLock(m_openDatabaseMapGuard);
+        if (!m_openDatabaseMap)
+            return;
+        for (auto& nameMap : m_openDatabaseMap->values()) {
+            for (auto& set : nameMap->values()) {
+                for (auto& database : *set)
+                    openDatabases.append(*database);
+            }
+        }
+    }
+    for (auto& database : openDatabases)
+        database->close();
+}
+
 void DatabaseTracker::interruptAllDatabasesForContext(const DatabaseContext* context)
 {
     Vector<RefPtr<DatabaseBackendBase>> openDatabases;

Modified: trunk/Source/WebCore/Modules/webdatabase/DatabaseTracker.h (184104 => 184105)


--- trunk/Source/WebCore/Modules/webdatabase/DatabaseTracker.h	2015-05-11 16:26:16 UTC (rev 184104)
+++ trunk/Source/WebCore/Modules/webdatabase/DatabaseTracker.h	2015-05-11 17:27:13 UTC (rev 184105)
@@ -74,6 +74,8 @@
 
     unsigned long long getMaxSizeForDatabase(const Database*);
 
+    WEBCORE_EXPORT void closeAllDatabases();
+
     void interruptAllDatabasesForContext(const DatabaseContext*);
 
 private:

Modified: trunk/Source/WebKit/mac/ChangeLog (184104 => 184105)


--- trunk/Source/WebKit/mac/ChangeLog	2015-05-11 16:26:16 UTC (rev 184104)
+++ trunk/Source/WebKit/mac/ChangeLog	2015-05-11 17:27:13 UTC (rev 184105)
@@ -1,3 +1,19 @@
+2015-05-11  Daniel Bates  <[email protected]>
+
+        [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.
+
+        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.
+
 2015-05-10  Sungmann Cho  <[email protected]>
 
         Get rid of the public item accessors in BackForwardClient

Modified: trunk/Source/WebKit/mac/Storage/WebDatabaseManager.mm (184104 => 184105)


--- trunk/Source/WebKit/mac/Storage/WebDatabaseManager.mm	2015-05-11 16:26:16 UTC (rev 184104)
+++ trunk/Source/WebKit/mac/Storage/WebDatabaseManager.mm	2015-05-11 17:27:13 UTC (rev 184105)
@@ -267,7 +267,10 @@
     if (getTransactionBackgroundTaskIdentifier() != invalidWebBackgroundTaskIdentifier())
         return;
     
-    setTransactionBackgroundTaskIdentifier(startBackgroundTask(^ { [WebDatabaseManager endBackgroundTask]; }));
+    setTransactionBackgroundTaskIdentifier(startBackgroundTask(^ {
+        DatabaseTracker::tracker().closeAllDatabases();
+        [WebDatabaseManager endBackgroundTask];
+    }));
 }
 
 + (void)endBackgroundTask

Modified: trunk/Source/WebKit2/ChangeLog (184104 => 184105)


--- trunk/Source/WebKit2/ChangeLog	2015-05-11 16:26:16 UTC (rev 184104)
+++ trunk/Source/WebKit2/ChangeLog	2015-05-11 17:27:13 UTC (rev 184105)
@@ -1,3 +1,80 @@
+2015-05-11  Daniel Bates  <[email protected]>
+
+        [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.
+
+        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.
+
 2015-05-10  Gyuyoung Kim  <[email protected]>
 
         Use Ref instead of PassRefPtr in WebCore/page

Modified: trunk/Source/WebKit2/NetworkProcess/NetworkProcess.cpp (184104 => 184105)


--- trunk/Source/WebKit2/NetworkProcess/NetworkProcess.cpp	2015-05-11 16:26:16 UTC (rev 184104)
+++ trunk/Source/WebKit2/NetworkProcess/NetworkProcess.cpp	2015-05-11 17:27:13 UTC (rev 184105)
@@ -132,7 +132,10 @@
 
 void NetworkProcess::didReceiveSyncMessage(IPC::Connection& connection, IPC::MessageDecoder& decoder, std::unique_ptr<IPC::MessageEncoder>& replyEncoder)
 {
-    messageReceiverMap().dispatchSyncMessage(connection, decoder, replyEncoder);
+    if (messageReceiverMap().dispatchSyncMessage(connection, decoder, replyEncoder))
+        return;
+
+    didReceiveSyncNetworkProcessMessage(connection, decoder, replyEncoder);
 }
 
 void NetworkProcess::didClose(IPC::Connection&)
@@ -505,6 +508,12 @@
     ChildProcess::terminate();
 }
 
+void NetworkProcess::processWillSuspendImminently(bool& handled)
+{
+    lowMemoryHandler(true);
+    handled = true;
+}
+
 void NetworkProcess::processWillSuspend()
 {
     lowMemoryHandler(true);

Modified: trunk/Source/WebKit2/NetworkProcess/NetworkProcess.h (184104 => 184105)


--- trunk/Source/WebKit2/NetworkProcess/NetworkProcess.h	2015-05-11 16:26:16 UTC (rev 184104)
+++ trunk/Source/WebKit2/NetworkProcess/NetworkProcess.h	2015-05-11 17:27:13 UTC (rev 184105)
@@ -78,6 +78,7 @@
     DownloadManager& downloadManager();
     bool canHandleHTTPSServerTrustEvaluation() const { return m_canHandleHTTPSServerTrustEvaluation; }
 
+    void processWillSuspendImminently(bool& handled);
     void processWillSuspend();
     void cancelProcessWillSuspend();
     void processDidResume();
@@ -122,6 +123,7 @@
 
     // Message Handlers
     void didReceiveNetworkProcessMessage(IPC::Connection&, IPC::MessageDecoder&);
+    void didReceiveSyncNetworkProcessMessage(IPC::Connection&, IPC::MessageDecoder&, std::unique_ptr<IPC::MessageEncoder>&);
     void initializeNetworkProcess(const NetworkProcessCreationParameters&);
     void createNetworkConnectionToWebProcess();
     void ensurePrivateBrowsingSession(WebCore::SessionID);

Modified: trunk/Source/WebKit2/NetworkProcess/NetworkProcess.messages.in (184104 => 184105)


--- trunk/Source/WebKit2/NetworkProcess/NetworkProcess.messages.in	2015-05-11 16:26:16 UTC (rev 184104)
+++ trunk/Source/WebKit2/NetworkProcess/NetworkProcess.messages.in	2015-05-11 17:27:13 UTC (rev 184105)
@@ -58,6 +58,7 @@
     ClearCacheForAllOrigins(uint32_t cachesToClear)
     SetCacheModel(uint32_t cacheModel);
 
+    ProcessWillSuspendImminently() -> (bool handled)
     ProcessWillSuspend()
     CancelProcessWillSuspend()
     ProcessDidResume()

Modified: trunk/Source/WebKit2/Shared/ChildProcessProxy.h (184104 => 184105)


--- trunk/Source/WebKit2/Shared/ChildProcessProxy.h	2015-05-11 16:26:16 UTC (rev 184104)
+++ trunk/Source/WebKit2/Shared/ChildProcessProxy.h	2015-05-11 17:27:13 UTC (rev 184105)
@@ -48,7 +48,7 @@
     void terminate();
 
     template<typename T> bool send(T&& message, uint64_t destinationID, unsigned messageSendFlags = 0);
-    template<typename T> bool sendSync(T&& message, typename T::Reply&&, uint64_t destinationID, std::chrono::milliseconds timeout = std::chrono::seconds(1));
+    template<typename T> bool sendSync(T&& message, typename T::Reply&&, uint64_t destinationID, std::chrono::milliseconds timeout = std::chrono::seconds(1), unsigned sendSyncFlags = 0);
     
     IPC::Connection* connection() const
     {
@@ -105,14 +105,14 @@
 }
 
 template<typename U> 
-bool ChildProcessProxy::sendSync(U&& message, typename U::Reply&& reply, uint64_t destinationID, std::chrono::milliseconds timeout)
+bool ChildProcessProxy::sendSync(U&& message, typename U::Reply&& reply, uint64_t destinationID, std::chrono::milliseconds timeout, unsigned sendSyncFlags)
 {
     COMPILE_ASSERT(U::isSync, SyncMessageExpected);
 
     if (!m_connection)
         return false;
 
-    return connection()->sendSync(std::forward<U>(message), WTF::move(reply), destinationID, timeout);
+    return connection()->sendSync(std::forward<U>(message), WTF::move(reply), destinationID, timeout, sendSyncFlags);
 }
 
 } // namespace WebKit

Modified: trunk/Source/WebKit2/UIProcess/Network/NetworkProcessProxy.cpp (184104 => 184105)


--- trunk/Source/WebKit2/UIProcess/Network/NetworkProcessProxy.cpp	2015-05-11 16:26:16 UTC (rev 184104)
+++ trunk/Source/WebKit2/UIProcess/Network/NetworkProcessProxy.cpp	2015-05-11 17:27:13 UTC (rev 184105)
@@ -313,6 +313,16 @@
     page->logDiagnosticMessageWithValue(message, description, value, shouldSample);
 }
 
+void NetworkProcessProxy::sendProcessWillSuspendImminently()
+{
+    if (!canSendMessage())
+        return;
+
+    bool handled = false;
+    sendSync(Messages::NetworkProcess::ProcessWillSuspendImminently(), Messages::NetworkProcess::ProcessWillSuspendImminently::Reply(handled),
+        0, std::chrono::seconds(1), IPC::InterruptWaitingIfSyncMessageArrives);
+}
+    
 void NetworkProcessProxy::sendProcessWillSuspend()
 {
     if (canSendMessage())

Modified: trunk/Source/WebKit2/UIProcess/Network/NetworkProcessProxy.h (184104 => 184105)


--- trunk/Source/WebKit2/UIProcess/Network/NetworkProcessProxy.h	2015-05-11 16:26:16 UTC (rev 184104)
+++ trunk/Source/WebKit2/UIProcess/Network/NetworkProcessProxy.h	2015-05-11 17:27:13 UTC (rev 184105)
@@ -69,6 +69,7 @@
     void setProcessSuppressionEnabled(bool);
 #endif
 
+    void sendProcessWillSuspendImminently() override;
     void sendProcessWillSuspend() override;
     void sendCancelProcessWillSuspend() override;
     void didCancelProcessSuspension();

Modified: trunk/Source/WebKit2/UIProcess/ProcessAssertion.cpp (184104 => 184105)


--- trunk/Source/WebKit2/UIProcess/ProcessAssertion.cpp	2015-05-11 16:26:16 UTC (rev 184104)
+++ trunk/Source/WebKit2/UIProcess/ProcessAssertion.cpp	2015-05-11 17:27:13 UTC (rev 184105)
@@ -46,7 +46,7 @@
 
     m_assertionState = assertionState;
 }
-    
+
 ProcessAndUIAssertion::ProcessAndUIAssertion(pid_t pid, AssertionState assertionState)
     : ProcessAssertion(pid, assertionState)
 {
@@ -60,7 +60,12 @@
 {
     ProcessAssertion::setState(assertionState);
 }
-    
+
+void ProcessAndUIAssertion::setClient(ProcessAssertionClient& client)
+{
+    ProcessAssertion::setClient(client);
 }
 
+}
+
 #endif // !PLATFORM(IOS)

Modified: trunk/Source/WebKit2/UIProcess/ProcessAssertion.h (184104 => 184105)


--- trunk/Source/WebKit2/UIProcess/ProcessAssertion.h	2015-05-11 16:26:16 UTC (rev 184104)
+++ trunk/Source/WebKit2/UIProcess/ProcessAssertion.h	2015-05-11 17:27:13 UTC (rev 184105)
@@ -39,27 +39,38 @@
     Foreground
 };
 
+class ProcessAssertionClient {
+public:
+    virtual ~ProcessAssertionClient() { };
+    virtual void assertionWillExpireImminently() = 0;
+};
+
 class ProcessAssertion {
 public:
     ProcessAssertion(pid_t, AssertionState);
     ~ProcessAssertion();
 
+    void setClient(ProcessAssertionClient& client) { m_client = &client; }
+    ProcessAssertionClient* client() { return m_client; }
+
     AssertionState state() const { return m_assertionState; }
-    
     void setState(AssertionState);
-    
+
 private:
 #if PLATFORM(IOS) && !PLATFORM(IOS_SIMULATOR)
     RetainPtr<BKSProcessAssertion> m_assertion;
 #endif
     AssertionState m_assertionState;
+    ProcessAssertionClient* m_client { nullptr };
 };
     
 class ProcessAndUIAssertion : public ProcessAssertion {
 public:
     ProcessAndUIAssertion(pid_t, AssertionState);
     ~ProcessAndUIAssertion();
-    
+
+    void setClient(ProcessAssertionClient&);
+
     void setState(AssertionState);
 };
     

Modified: trunk/Source/WebKit2/UIProcess/ProcessThrottler.cpp (184104 => 184105)


--- trunk/Source/WebKit2/UIProcess/ProcessThrottler.cpp	2015-05-11 16:26:16 UTC (rev 184104)
+++ trunk/Source/WebKit2/UIProcess/ProcessThrottler.cpp	2015-05-11 17:27:13 UTC (rev 184105)
@@ -88,6 +88,7 @@
 {
     m_suspendTimer.stop();
     m_assertion = std::make_unique<ProcessAndUIAssertion>(pid, assertionState());
+    m_assertion->setClient(*this);
 }
     
 void ProcessThrottler::suspendTimerFired()
@@ -109,4 +110,9 @@
     ASSERT(m_suspendMessageCount >= 0);
 }
 
+void ProcessThrottler::assertionWillExpireImminently()
+{
+    m_process->sendProcessWillSuspendImminently();
 }
+
+}

Modified: trunk/Source/WebKit2/UIProcess/ProcessThrottler.h (184104 => 184105)


--- trunk/Source/WebKit2/UIProcess/ProcessThrottler.h	2015-05-11 16:26:16 UTC (rev 184104)
+++ trunk/Source/WebKit2/UIProcess/ProcessThrottler.h	2015-05-11 17:27:13 UTC (rev 184105)
@@ -41,7 +41,7 @@
 
 class ProcessThrottlerClient;
 
-class ProcessThrottler {
+class ProcessThrottler : private ProcessAssertionClient {
 public:
     enum ForegroundActivityTokenType { };
     typedef RefCounter::Token<ForegroundActivityTokenType> ForegroundActivityToken;
@@ -56,13 +56,16 @@
     void didConnectToProcess(pid_t);
     void processReadyToSuspend();
     void didCancelProcessSuspension();
-    
+
 private:
     AssertionState assertionState();
     void updateAssertion();
     void updateAssertionNow();
     void suspendTimerFired();
-    
+
+    // ProcessAssertionClient
+    void assertionWillExpireImminently() override;
+
     ProcessThrottlerClient* m_process;
     std::unique_ptr<ProcessAndUIAssertion> m_assertion;
     RunLoop::Timer<ProcessThrottler> m_suspendTimer;

Modified: trunk/Source/WebKit2/UIProcess/ProcessThrottlerClient.h (184104 => 184105)


--- trunk/Source/WebKit2/UIProcess/ProcessThrottlerClient.h	2015-05-11 16:26:16 UTC (rev 184104)
+++ trunk/Source/WebKit2/UIProcess/ProcessThrottlerClient.h	2015-05-11 17:27:13 UTC (rev 184105)
@@ -32,6 +32,7 @@
 public:
     virtual ~ProcessThrottlerClient() { }
 
+    virtual void sendProcessWillSuspendImminently() = 0;
     virtual void sendProcessWillSuspend() = 0;
     virtual void sendCancelProcessWillSuspend() = 0;
     virtual void sendProcessDidResume() = 0;

Modified: trunk/Source/WebKit2/UIProcess/WebProcessProxy.cpp (184104 => 184105)


--- trunk/Source/WebKit2/UIProcess/WebProcessProxy.cpp	2015-05-11 16:26:16 UTC (rev 184104)
+++ trunk/Source/WebKit2/UIProcess/WebProcessProxy.cpp	2015-05-11 17:27:13 UTC (rev 184105)
@@ -889,6 +889,16 @@
     return UserData::transform(object, Transformer());
 }
 
+void WebProcessProxy::sendProcessWillSuspendImminently()
+{
+    if (!canSendMessage())
+        return;
+
+    bool handled = false;
+    sendSync(Messages::WebProcess::ProcessWillSuspendImminently(), Messages::WebProcess::ProcessWillSuspendImminently::Reply(handled),
+        0, std::chrono::seconds(1), IPC::InterruptWaitingIfSyncMessageArrives);
+}
+
 void WebProcessProxy::sendProcessWillSuspend()
 {
     if (canSendMessage())

Modified: trunk/Source/WebKit2/UIProcess/WebProcessProxy.h (184104 => 184105)


--- trunk/Source/WebKit2/UIProcess/WebProcessProxy.h	2015-05-11 16:26:16 UTC (rev 184104)
+++ trunk/Source/WebKit2/UIProcess/WebProcessProxy.h	2015-05-11 17:27:13 UTC (rev 184105)
@@ -143,6 +143,7 @@
 
     void windowServerConnectionStateChanged();
 
+    void sendProcessWillSuspendImminently() override;
     void sendProcessWillSuspend() override;
     void processReadyToSuspend();
     void sendCancelProcessWillSuspend() override;

Modified: trunk/Source/WebKit2/UIProcess/ios/ProcessAssertionIOS.mm (184104 => 184105)


--- trunk/Source/WebKit2/UIProcess/ios/ProcessAssertionIOS.mm	2015-05-11 16:26:16 UTC (rev 184104)
+++ trunk/Source/WebKit2/UIProcess/ios/ProcessAssertionIOS.mm	2015-05-11 17:27:13 UTC (rev 184105)
@@ -30,9 +30,13 @@
 
 #import "BKSProcessAssertionSPI.h"
 #import <UIKit/UIApplication.h>
+#import <wtf/HashSet.h>
+#import <wtf/Vector.h>
 
 #if !PLATFORM(IOS_SIMULATOR)
 
+using WebKit::ProcessAssertionClient;
+
 @interface WKProcessAssertionBackgroundTaskManager : NSObject
 
 + (WKProcessAssertionBackgroundTaskManager *)shared;
@@ -40,6 +44,9 @@
 - (void)incrementNeedsToRunInBackgroundCount;
 - (void)decrementNeedsToRunInBackgroundCount;
 
+- (void)addClient:(ProcessAssertionClient&)client;
+- (void)removeClient:(ProcessAssertionClient&)client;
+
 @end
 
 @implementation WKProcessAssertionBackgroundTaskManager
@@ -47,6 +54,7 @@
     unsigned _needsToRunInBackgroundCount;
     BOOL _appIsBackground;
     UIBackgroundTaskIdentifier _backgroundTask;
+    HashSet<ProcessAssertionClient*> _clients;
 }
 
 + (WKProcessAssertionBackgroundTaskManager *)shared
@@ -83,6 +91,16 @@
     [super dealloc];
 }
 
+- (void)addClient:(ProcessAssertionClient&)client
+{
+    _clients.add(&client);
+}
+
+- (void)removeClient:(ProcessAssertionClient&)client
+{
+    _clients.remove(&client);
+}
+
 - (void)_updateBackgroundTask
 {
     bool shouldHoldTask = _needsToRunInBackgroundCount && _appIsBackground;
@@ -90,6 +108,10 @@
     if (shouldHoldTask && _backgroundTask == UIBackgroundTaskInvalid) {
         _backgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithName:@"com.apple.WebKit.ProcessAssertion" expirationHandler:^{
             NSLog(@"Background task expired while holding WebKit ProcessAssertion.");
+            Vector<ProcessAssertionClient*> clientsToNotify;
+            copyToVector(_clients, clientsToNotify);
+            for (auto* client : clientsToNotify)
+                client->assertionWillExpireImminently();
             [[UIApplication sharedApplication] endBackgroundTask:_backgroundTask];
             _backgroundTask = UIBackgroundTaskInvalid;
         }];
@@ -160,6 +182,8 @@
 
 ProcessAssertion::~ProcessAssertion()
 {
+    if (ProcessAssertionClient* client = this->client())
+        [[WKProcessAssertionBackgroundTaskManager shared] removeClient:*client];
     [m_assertion invalidate];
 }
 
@@ -195,6 +219,14 @@
     ProcessAssertion::setState(assertionState);
 }
 
+void ProcessAndUIAssertion::setClient(ProcessAssertionClient& newClient)
+{
+    [[WKProcessAssertionBackgroundTaskManager shared] addClient:newClient];
+    if (ProcessAssertionClient* oldClient = this->client())
+        [[WKProcessAssertionBackgroundTaskManager shared] removeClient:*oldClient];
+    ProcessAssertion::setClient(newClient);
+}
+
 } // namespace WebKit
 
 #else // PLATFORM(IOS_SIMULATOR)
@@ -229,6 +261,11 @@
     ProcessAssertion::setState(assertionState);
 }
 
+void ProcessAndUIAssertion::setClient(ProcessAssertionClient& newClient)
+{
+    ProcessAssertion::setClient(newClient);
+}
+
 } // namespace WebKit
 
 #endif // PLATFORM(IOS_SIMULATOR)

Modified: trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebDatabaseManager.cpp (184104 => 184105)


--- trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebDatabaseManager.cpp	2015-05-11 16:26:16 UTC (rev 184104)
+++ trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebDatabaseManager.cpp	2015-05-11 17:27:13 UTC (rev 184105)
@@ -142,6 +142,11 @@
     DatabaseManager::singleton().setPauseAllDatabases(pauseAllDatabases);
 }
 
+void WebDatabaseManager::closeAllDatabases() const
+{
+    DatabaseManager::singleton().closeAllDatabases();
+}
+
 void WebDatabaseManager::setQuotaForOrigin(const String& originIdentifier, unsigned long long quota) const
 {
     // If the quota is set to a value lower than the current usage, that quota will

Modified: trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebDatabaseManager.h (184104 => 184105)


--- trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebDatabaseManager.h	2015-05-11 16:26:16 UTC (rev 184104)
+++ trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebDatabaseManager.h	2015-05-11 17:27:13 UTC (rev 184105)
@@ -48,6 +48,8 @@
 
     void setPauseAllDatabases(bool);
 
+    void closeAllDatabases() const;
+
 private:
     // WebProcessSupplement
     virtual void initialize(const WebProcessCreationParameters&) override;

Modified: trunk/Source/WebKit2/WebProcess/WebProcess.cpp (184104 => 184105)


--- trunk/Source/WebKit2/WebProcess/WebProcess.cpp	2015-05-11 16:26:16 UTC (rev 184104)
+++ trunk/Source/WebKit2/WebProcess/WebProcess.cpp	2015-05-11 17:27:13 UTC (rev 184105)
@@ -608,7 +608,7 @@
     if (messageReceiverMap().dispatchSyncMessage(connection, decoder, replyEncoder))
         return;
 
-    LOG_ERROR("Unhandled synchronous web process message '%s:%s'", decoder.messageReceiverName().toString().data(), decoder.messageName().toString().data());
+    didReceiveSyncWebProcessMessage(connection, decoder, replyEncoder);
 }
 
 void WebProcess::didReceiveMessage(IPC::Connection& connection, IPC::MessageDecoder& decoder)
@@ -1217,18 +1217,33 @@
     }
 }
 #endif
-    
-void WebProcess::processWillSuspend()
+
+void WebProcess::prepareToSuspend(ShouldAcknowledgeWhenReadyToSuspend shouldAcknowledgeWhenReadyToSuspend)
 {
     MemoryPressureHandler::singleton().releaseMemory(true);
     setAllLayerTreeStatesFrozen(true);
 
-    if (!markAllLayersVolatileIfPossible())
-        m_processSuspensionCleanupTimer.startRepeating(std::chrono::milliseconds(20));
-    else
-        parentProcessConnection()->send(Messages::WebProcessProxy::ProcessReadyToSuspend(), 0);
+    if (markAllLayersVolatileIfPossible()) {
+        if (shouldAcknowledgeWhenReadyToSuspend == ShouldAcknowledgeWhenReadyToSuspend::Yes)
+            parentProcessConnection()->send(Messages::WebProcessProxy::ProcessReadyToSuspend(), 0);
+        return;
+    }
+    m_shouldAcknowledgeWhenReadyToSuspend = shouldAcknowledgeWhenReadyToSuspend;
+    m_processSuspensionCleanupTimer.startRepeating(std::chrono::milliseconds(20));
 }
 
+void WebProcess::processWillSuspendImminently(bool& handled)
+{
+    supplement<WebDatabaseManager>()->closeAllDatabases();
+    prepareToSuspend(ShouldAcknowledgeWhenReadyToSuspend::No);
+    handled = true;
+}
+
+void WebProcess::processWillSuspend()
+{
+    prepareToSuspend(ShouldAcknowledgeWhenReadyToSuspend::Yes);
+}
+
 void WebProcess::cancelProcessWillSuspend()
 {
     setAllLayerTreeStatesFrozen(false);
@@ -1263,14 +1278,16 @@
 
 void WebProcess::processSuspensionCleanupTimerFired()
 {
-    if (markAllLayersVolatileIfPossible()) {
-        m_processSuspensionCleanupTimer.stop();
+    if (!markAllLayersVolatileIfPossible())
+        return;
+    m_processSuspensionCleanupTimer.stop();
+    if (m_shouldAcknowledgeWhenReadyToSuspend == ShouldAcknowledgeWhenReadyToSuspend::Yes)
         parentProcessConnection()->send(Messages::WebProcessProxy::ProcessReadyToSuspend(), 0);
-    }
 }
     
 void WebProcess::processDidResume()
 {
+    m_processSuspensionCleanupTimer.stop();
     setAllLayerTreeStatesFrozen(false);
 }
 

Modified: trunk/Source/WebKit2/WebProcess/WebProcess.h (184104 => 184105)


--- trunk/Source/WebKit2/WebProcess/WebProcess.h	2015-05-11 16:26:16 UTC (rev 184104)
+++ trunk/Source/WebKit2/WebProcess/WebProcess.h	2015-05-11 17:27:13 UTC (rev 184105)
@@ -184,6 +184,7 @@
     void allowSpecificHTTPSCertificateForHost(const WebCore::CertificateInfo&, const String& host);
 #endif
 
+    void processWillSuspendImminently(bool& handled);
     void processWillSuspend();
     void cancelProcessWillSuspend();
     bool markAllLayersVolatileIfPossible();
@@ -282,6 +283,9 @@
     void handleInjectedBundleMessage(const String& messageName, const UserData& messageBody);
     void setInjectedBundleParameter(const String& key, const IPC::DataReference&);
 
+    enum class ShouldAcknowledgeWhenReadyToSuspend { No, Yes };
+    void prepareToSuspend(ShouldAcknowledgeWhenReadyToSuspend);
+
     // ChildProcess
     virtual void initializeProcess(const ChildProcessInitializationParameters&) override;
     virtual void initializeProcessName(const ChildProcessInitializationParameters&) override;
@@ -307,6 +311,7 @@
 
     // Implemented in generated WebProcessMessageReceiver.cpp
     void didReceiveWebProcessMessage(IPC::Connection&, IPC::MessageDecoder&);
+    void didReceiveSyncWebProcessMessage(IPC::Connection&, IPC::MessageDecoder&, std::unique_ptr<IPC::MessageEncoder>&);
 
     // WebOriginDataManagerSupplement
     virtual void getOrigins(WKOriginDataTypes, std::function<void (const Vector<SecurityOriginData>&)> completion) override;
@@ -381,6 +386,8 @@
 #if PLATFORM(IOS)
     WebSQLiteDatabaseTracker m_webSQLiteDatabaseTracker;
 #endif
+
+    ShouldAcknowledgeWhenReadyToSuspend m_shouldAcknowledgeWhenReadyToSuspend;
 };
 
 } // namespace WebKit

Modified: trunk/Source/WebKit2/WebProcess/WebProcess.messages.in (184104 => 184105)


--- trunk/Source/WebKit2/WebProcess/WebProcess.messages.in	2015-05-11 16:26:16 UTC (rev 184104)
+++ trunk/Source/WebKit2/WebProcess/WebProcess.messages.in	2015-05-11 17:27:13 UTC (rev 184105)
@@ -100,6 +100,7 @@
     SetEnabledServices(bool hasImageServices, bool hasSelectionServices, bool hasRichContentServices)
 #endif
 
+    ProcessWillSuspendImminently() -> (bool handled)
     ProcessWillSuspend()
     CancelProcessWillSuspend()
     ProcessDidResume()
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to