Modified: trunk/Source/WebCore/ChangeLog (114979 => 114980)
--- trunk/Source/WebCore/ChangeLog 2012-04-24 01:31:45 UTC (rev 114979)
+++ trunk/Source/WebCore/ChangeLog 2012-04-24 01:33:00 UTC (rev 114980)
@@ -1,3 +1,26 @@
+2012-04-22 Martin Robinson <mrobin...@igalia.com>
+
+ REGRESSION(113604): [Soup] Some pages that use synchronous XMLHttpRequests freeze the browser
+ https://bugs.webkit.org/show_bug.cgi?id=84560
+
+ Reviewed by Xan Lopez.
+
+ When kicking off a synchronous XMLHttpRequest, add one to the connection
+ limit. This ensures that when a page starts a synchronous request, while
+ already at the connection limit the request will not deadlock.
+
+ * platform/network/soup/ResourceHandleSoup.cpp:
+ (WebCore::WebCoreSynchronousLoader::WebCoreSynchronousLoader): Accept a new SoupSession
+ argument so that we can get the correct SoupSession for the networking context. Bump
+ the connection limit.
+ (WebCore::WebCoreSynchronousLoader::~WebCoreSynchronousLoader): Decrement the connection limit.
+ (WebCore::WebCoreSynchronousLoader::adjustMaxConnections): Added this helper.
+ (WebCoreSynchronousLoader): Added a new SoupSession member.
+ (WebCore::sessionFromContext): Added this helper.
+ (WebCore::ResourceHandleInternal::soupSession): Use the new sessionFromContext helper.
+ (WebCore::ResourceHandle::loadResourceSynchronously): Pass the SoupSession from the NetworkingContext
+ to the synchronous loader.
+
2012-04-23 Sheriff Bot <webkit.review....@gmail.com>
Unreviewed, rolling out r114965.
Modified: trunk/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp (114979 => 114980)
--- trunk/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp 2012-04-24 01:31:45 UTC (rev 114979)
+++ trunk/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp 2012-04-24 01:33:00 UTC (rev 114980)
@@ -75,9 +75,10 @@
WTF_MAKE_NONCOPYABLE(WebCoreSynchronousLoader);
public:
- WebCoreSynchronousLoader(ResourceError& error, ResourceResponse& response, Vector<char>& data)
+ WebCoreSynchronousLoader(ResourceError& error, ResourceResponse& response, SoupSession* session, Vector<char>& data)
: m_error(error)
, m_response(response)
+ , m_session(session)
, m_data(data)
, m_finished(false)
{
@@ -88,14 +89,33 @@
GRefPtr<GMainContext> innerMainContext = adoptGRef(g_main_context_new());
g_main_context_push_thread_default(innerMainContext.get());
m_mainLoop = g_main_loop_new(innerMainContext.get(), false);
+
+ adjustMaxConnections(1);
}
~WebCoreSynchronousLoader()
{
+ adjustMaxConnections(-1);
g_main_context_pop_thread_default(g_main_context_get_thread_default());
loadingSynchronousRequest = false;
}
+ void adjustMaxConnections(int adjustment)
+ {
+ int maxConnections, maxConnectionsPerHost;
+ g_object_get(m_session,
+ SOUP_SESSION_MAX_CONNS, &maxConnections,
+ SOUP_SESSION_MAX_CONNS_PER_HOST, &maxConnectionsPerHost,
+ NULL);
+ maxConnections += adjustment;
+ maxConnectionsPerHost += adjustment;
+ g_object_set(m_session,
+ SOUP_SESSION_MAX_CONNS, maxConnections,
+ SOUP_SESSION_MAX_CONNS_PER_HOST, maxConnectionsPerHost,
+ NULL);
+
+ }
+
virtual bool isSynchronousClient()
{
return true;
@@ -133,6 +153,7 @@
private:
ResourceError& m_error;
ResourceResponse& m_response;
+ SoupSession* m_session;
Vector<char>& m_data;
bool m_finished;
GRefPtr<GMainLoop> m_mainLoop;
@@ -151,9 +172,14 @@
{
}
+static SoupSession* sessionFromContext(NetworkingContext* context)
+{
+ return (context && context->isValid()) ? context->soupSession() : ResourceHandle::defaultSession();
+}
+
SoupSession* ResourceHandleInternal::soupSession()
{
- return (m_context && m_context->isValid()) ? m_context->soupSession() : ResourceHandle::defaultSession();
+ return sessionFromContext(m_context.get());
}
ResourceHandle::~ResourceHandle()
@@ -750,8 +776,12 @@
return;
}
#endif
+
+ ASSERT(!loadingSynchronousRequest);
+ if (loadingSynchronousRequest) // In practice this cannot happen, but if for some reason it does,
+ return; // we want to avoid accidentally going into an infinite loop of requests.
- WebCoreSynchronousLoader syncLoader(error, response, data);
+ WebCoreSynchronousLoader syncLoader(error, response, sessionFromContext(context), data);
RefPtr<ResourceHandle> handle = create(context, request, &syncLoader, false /*defersLoading*/, false /*shouldContentSniff*/);
if (!handle)
return;