Diff
Modified: trunk/Source/WebKit2/ChangeLog (145163 => 145164)
--- trunk/Source/WebKit2/ChangeLog 2013-03-08 01:31:02 UTC (rev 145163)
+++ trunk/Source/WebKit2/ChangeLog 2013-03-08 01:31:19 UTC (rev 145164)
@@ -1,3 +1,40 @@
+2013-03-07 Mark Lam <[email protected]>
+
+ WebPageProxy::exceededDatabaseQuota() needs to be serialized.
+ https://bugs.webkit.org/show_bug.cgi?id=111631.
+
+ Reviewed by Geoffrey Garen.
+
+ Previously, WebPageProxy::exceededDatabaseQuota() is called synchronously
+ with script execution in the WebProcess. Hence, it is never called in a
+ recursive manner.
+
+ In webkit2, we can have multiple WebProcesses concurrently triggering a
+ call to this function. While the function is waiting on feedback from a
+ UI dialog, the wait loop may re-enter the function to service a second
+ request to call this function from another WebProcess. This results in
+ problems where some of the WebProcesses will not get a proper reply, and
+ therefore hangs perpetually waiting for a non-forthcoming reply.
+
+ This changeset changes the function to queue the requests and ensure
+ that we do not recursively callback to the UI client.
+
+ * Platform/CoreIPC/HandleMessage.h:
+ (CoreIPC::callMemberFunction):
+ * UIProcess/WebPageProxy.cpp:
+ (ExceededDatabaseQuotaRecords):
+ (Record):
+ (WebKit::ExceededDatabaseQuotaRecords::areBeingProcessed):
+ (WebKit::ExceededDatabaseQuotaRecords::ExceededDatabaseQuotaRecords):
+ (WebKit::ExceededDatabaseQuotaRecords::~ExceededDatabaseQuotaRecords):
+ (WebKit::ExceededDatabaseQuotaRecords::shared):
+ (WebKit::ExceededDatabaseQuotaRecords::createRecord):
+ (WebKit::ExceededDatabaseQuotaRecords::add):
+ (WebKit::ExceededDatabaseQuotaRecords::next):
+ (WebKit::WebPageProxy::exceededDatabaseQuota):
+ * UIProcess/WebPageProxy.h:
+ * UIProcess/WebPageProxy.messages.in:
+
2013-03-07 Jeffrey Pfau <[email protected]>
CFNetwork cache partitioning does not work properly on subdomains
Modified: trunk/Source/WebKit2/Platform/CoreIPC/HandleMessage.h (145163 => 145164)
--- trunk/Source/WebKit2/Platform/CoreIPC/HandleMessage.h 2013-03-08 01:31:02 UTC (rev 145163)
+++ trunk/Source/WebKit2/Platform/CoreIPC/HandleMessage.h 2013-03-08 01:31:19 UTC (rev 145164)
@@ -216,6 +216,12 @@
(object->*function)(args.argument1, args.argument2, delayedReply);
}
+template<typename C, typename MF, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename R>
+void callMemberFunction(const Arguments8<P1, P2, P3, P4, P5, P6, P7, P8>& args, PassRefPtr<R> delayedReply, C* object, MF function)
+{
+ (object->*function)(args.argument1, args.argument2, args.argument3, args.argument4, args.argument5, args.argument6, args.argument7, args.argument8, delayedReply);
+}
+
// Dispatch functions with connection parameter.
template<typename C, typename MF>
void callMemberFunction(Connection* connection, const Arguments0&, C* object, MF function)
Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp (145163 => 145164)
--- trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp 2013-03-08 01:31:02 UTC (rev 145163)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp 2013-03-08 01:31:19 UTC (rev 145164)
@@ -132,6 +132,77 @@
DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, webPageProxyCounter, ("WebPageProxy"));
+class ExceededDatabaseQuotaRecords {
+ WTF_MAKE_NONCOPYABLE(ExceededDatabaseQuotaRecords); WTF_MAKE_FAST_ALLOCATED;
+public:
+ struct Record {
+ uint64_t frameID;
+ String originIdentifier;
+ String databaseName;
+ String displayName;
+ uint64_t currentQuota;
+ uint64_t currentOriginUsage;
+ uint64_t currentDatabaseUsage;
+ uint64_t expectedUsage;
+ RefPtr<Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply> reply;
+ };
+
+ static ExceededDatabaseQuotaRecords& shared();
+
+ PassOwnPtr<Record> createRecord(uint64_t frameID, String originIdentifier,
+ String databaseName, String displayName, uint64_t currentQuota,
+ uint64_t currentOriginUsage, uint64_t currentDatabaseUsage, uint64_t expectedUsage,
+ PassRefPtr<Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply>);
+
+ void add(PassOwnPtr<Record>);
+ bool areBeingProcessed() const { return m_currentRecord; }
+ Record* next();
+
+private:
+ ExceededDatabaseQuotaRecords() { }
+ ~ExceededDatabaseQuotaRecords() { }
+
+ Deque<OwnPtr<Record> > m_records;
+ OwnPtr<Record> m_currentRecord;
+};
+
+ExceededDatabaseQuotaRecords& ExceededDatabaseQuotaRecords::shared()
+{
+ DEFINE_STATIC_LOCAL(ExceededDatabaseQuotaRecords, records, ());
+ return records;
+}
+
+PassOwnPtr<ExceededDatabaseQuotaRecords::Record> ExceededDatabaseQuotaRecords::createRecord(
+ uint64_t frameID, String originIdentifier, String databaseName, String displayName,
+ uint64_t currentQuota, uint64_t currentOriginUsage, uint64_t currentDatabaseUsage,
+ uint64_t expectedUsage, PassRefPtr<Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply> reply)
+{
+ OwnPtr<Record> record = adoptPtr(new Record);
+ record->frameID = frameID;
+ record->originIdentifier = originIdentifier;
+ record->databaseName = databaseName;
+ record->displayName = displayName;
+ record->currentQuota = currentQuota;
+ record->currentOriginUsage = currentOriginUsage;
+ record->currentDatabaseUsage = currentDatabaseUsage;
+ record->expectedUsage = expectedUsage;
+ record->reply = reply;
+ return record.release();
+}
+
+void ExceededDatabaseQuotaRecords::add(PassOwnPtr<ExceededDatabaseQuotaRecords::Record> record)
+{
+ m_records.append(record);
+}
+
+ExceededDatabaseQuotaRecords::Record* ExceededDatabaseQuotaRecords::next()
+{
+ m_currentRecord.clear();
+ if (!m_records.isEmpty())
+ m_currentRecord = m_records.takeFirst();
+ return m_currentRecord.get();
+}
+
#if !LOG_DISABLED
static const char* webKeyboardEventTypeString(WebEvent::Type type)
{
@@ -3935,14 +4006,31 @@
m_loaderClient.didReceiveAuthenticationChallengeInFrame(this, frame, authenticationChallenge.get());
}
-void WebPageProxy::exceededDatabaseQuota(uint64_t frameID, const String& originIdentifier, const String& databaseName, const String& displayName, uint64_t currentQuota, uint64_t currentOriginUsage, uint64_t currentDatabaseUsage, uint64_t expectedUsage, uint64_t& newQuota)
+void WebPageProxy::exceededDatabaseQuota(uint64_t frameID, const String& originIdentifier, const String& databaseName, const String& displayName, uint64_t currentQuota, uint64_t currentOriginUsage, uint64_t currentDatabaseUsage, uint64_t expectedUsage, PassRefPtr<Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply> reply)
{
- WebFrameProxy* frame = m_process->webFrame(frameID);
- MESSAGE_CHECK(frame);
+ ExceededDatabaseQuotaRecords& records = ExceededDatabaseQuotaRecords::shared();
+ OwnPtr<ExceededDatabaseQuotaRecords::Record> newRecord = records.createRecord(frameID,
+ originIdentifier, databaseName, displayName, currentQuota, currentOriginUsage,
+ currentDatabaseUsage, expectedUsage, reply);
+ records.add(newRecord.release());
- RefPtr<WebSecurityOrigin> origin = WebSecurityOrigin::createFromDatabaseIdentifier(originIdentifier);
+ if (records.areBeingProcessed())
+ return;
- newQuota = m_uiClient.exceededDatabaseQuota(this, frame, origin.get(), databaseName, displayName, currentQuota, currentOriginUsage, currentDatabaseUsage, expectedUsage);
+ ExceededDatabaseQuotaRecords::Record* record = records.next();
+ while (record) {
+ WebFrameProxy* frame = m_process->webFrame(record->frameID);
+ MESSAGE_CHECK(frame);
+
+ RefPtr<WebSecurityOrigin> origin = WebSecurityOrigin::createFromDatabaseIdentifier(record->originIdentifier);
+
+ uint64_t newQuota = m_uiClient.exceededDatabaseQuota(this, frame, origin.get(),
+ record->databaseName, record->displayName, record->currentQuota,
+ record->currentOriginUsage, record->currentDatabaseUsage, record->expectedUsage);
+
+ record->reply->send(newQuota);
+ record = records.next();
+ }
}
void WebPageProxy::requestGeolocationPermissionForFrame(uint64_t geolocationID, uint64_t frameID, String originIdentifier)
Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.h (145163 => 145164)
--- trunk/Source/WebKit2/UIProcess/WebPageProxy.h 2013-03-08 01:31:02 UTC (rev 145163)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.h 2013-03-08 01:31:19 UTC (rev 145164)
@@ -49,10 +49,11 @@
#include "WebHitTestResult.h"
#include "WebLoaderClient.h"
#include "WebPageContextMenuClient.h"
+#include <WebCore/AlternativeTextClient.h> // FIXME: Needed by WebPageProxyMessages.h for DICTATION_ALTERNATIVES.
+#include "WebPageProxyMessages.h"
#include "WebPolicyClient.h"
#include "WebPopupMenuProxy.h"
#include "WebUIClient.h"
-#include <WebCore/AlternativeTextClient.h>
#include <WebCore/Color.h>
#include <WebCore/DragActions.h>
#include <WebCore/DragSession.h>
@@ -857,7 +858,7 @@
void pageDidScroll();
void runOpenPanel(uint64_t frameID, const WebCore::FileChooserSettings&);
void printFrame(uint64_t frameID);
- void exceededDatabaseQuota(uint64_t frameID, const String& originIdentifier, const String& databaseName, const String& displayName, uint64_t currentQuota, uint64_t currentOriginUsage, uint64_t currentDatabaseUsage, uint64_t expectedUsage, uint64_t& newQuota);
+ void exceededDatabaseQuota(uint64_t frameID, const String& originIdentifier, const String& databaseName, const String& displayName, uint64_t currentQuota, uint64_t currentOriginUsage, uint64_t currentDatabaseUsage, uint64_t expectedUsage, PassRefPtr<Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply>);
void requestGeolocationPermissionForFrame(uint64_t geolocationID, uint64_t frameID, String originIdentifier);
void runModal();
void notifyScrollerThumbIsVisibleInRect(const WebCore::IntRect&);
Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in (145163 => 145164)
--- trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in 2013-03-08 01:31:02 UTC (rev 145163)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in 2013-03-08 01:31:19 UTC (rev 145164)
@@ -212,7 +212,7 @@
DidReceiveAuthenticationChallenge(uint64_t frameID, WebCore::AuthenticationChallenge challenge, uint64_t challengeID)
# Database messages
- ExceededDatabaseQuota(uint64_t frameID, WTF::String originIdentifier, WTF::String databaseName, WTF::String databaseDisplayName, uint64_t currentQuota, uint64_t currentOriginUsage, uint64_t currentDatabaseUsage, uint64_t expectedUsage) -> (uint64_t newQuota)
+ ExceededDatabaseQuota(uint64_t frameID, WTF::String originIdentifier, WTF::String databaseName, WTF::String databaseDisplayName, uint64_t currentQuota, uint64_t currentOriginUsage, uint64_t currentDatabaseUsage, uint64_t expectedUsage) -> (uint64_t newQuota) Delayed
# Geolocation messages
RequestGeolocationPermissionForFrame(uint64_t geolocationID, uint64_t frameID, WTF::String originIdentifier)