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()