<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[129636] trunk/Source/WebCore</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/129636">129636</a></dd>
<dt>Author</dt> <dd>dominik.rottsches@intel.com</dd>
<dt>Date</dt> <dd>2012-09-26 07:08:26 -0700 (Wed, 26 Sep 2012)</dd>
</dl>

<h3>Log Message</h3>
<pre>[soup] Obey setTimeoutInterval in soup backend
https://bugs.webkit.org/show_bug.cgi?id=94796

Reviewed by Gustavo Noronha Silva.

Implementing ResourceHandle's setTimeoutInterval support for the soup backend.
This is preparatory work for bug 74802, timeout support for XHR2. The patch
has been successfully tested in combination with my work-in-progress
for that bug.

No new tests yet, tests will be added with the patch in bug 74802.

* platform/network/ResourceHandleInternal.h:
(WebCore::ResourceHandleInternal::ResourceHandleInternal): Adding a timeout source.
(ResourceHandleInternal):
* platform/network/soup/ResourceHandleSoup.cpp:
(WebCore):
(WebCore::cleanupSoupRequestOperation): Resetting the timer.
(WebCore::sendRequestCallback): Stopping the timer.
(WebCore::startHTTPRequest): Starting a timeout timer before the async request.
(WebCore::ResourceHandle::platformSetDefersLoading): Starting a timeout timer before the async request.
(WebCore::requestTimeoutCallback): Preparing a corresponding resource error and notifying clients of failure.
(WebCore::startNonHTTPRequest): Starting a timeout timer before the async request.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkResourceHandleInternalh">trunk/Source/WebCore/platform/network/ResourceHandleInternal.h</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworksoupResourceHandleSoupcpp">trunk/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (129635 => 129636)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2012-09-26 14:08:20 UTC (rev 129635)
+++ trunk/Source/WebCore/ChangeLog        2012-09-26 14:08:26 UTC (rev 129636)
</span><span class="lines">@@ -1,3 +1,29 @@
</span><ins>+2012-09-26  Dominik Röttsches  &lt;dominik.rottsches@intel.com&gt;
+
+        [soup] Obey setTimeoutInterval in soup backend
+        https://bugs.webkit.org/show_bug.cgi?id=94796
+
+        Reviewed by Gustavo Noronha Silva.
+
+        Implementing ResourceHandle's setTimeoutInterval support for the soup backend.
+        This is preparatory work for bug 74802, timeout support for XHR2. The patch
+        has been successfully tested in combination with my work-in-progress
+        for that bug.
+
+        No new tests yet, tests will be added with the patch in bug 74802.
+
+        * platform/network/ResourceHandleInternal.h:
+        (WebCore::ResourceHandleInternal::ResourceHandleInternal): Adding a timeout source.
+        (ResourceHandleInternal):
+        * platform/network/soup/ResourceHandleSoup.cpp:
+        (WebCore):
+        (WebCore::cleanupSoupRequestOperation): Resetting the timer.
+        (WebCore::sendRequestCallback): Stopping the timer.
+        (WebCore::startHTTPRequest): Starting a timeout timer before the async request.
+        (WebCore::ResourceHandle::platformSetDefersLoading): Starting a timeout timer before the async request.
+        (WebCore::requestTimeoutCallback): Preparing a corresponding resource error and notifying clients of failure.
+        (WebCore::startNonHTTPRequest): Starting a timeout timer before the async request.
+
</ins><span class="cx"> 2012-09-26  Andrey Kosyakov  &lt;caseq@chromium.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Web Inspector: paint inspector overlay on a transparency layer
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkResourceHandleInternalh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/ResourceHandleInternal.h (129635 => 129636)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/ResourceHandleInternal.h        2012-09-26 14:08:20 UTC (rev 129635)
+++ trunk/Source/WebCore/platform/network/ResourceHandleInternal.h        2012-09-26 14:08:26 UTC (rev 129636)
</span><span class="lines">@@ -187,6 +187,7 @@
</span><span class="cx">         GRefPtr&lt;GInputStream&gt; m_inputStream;
</span><span class="cx">         GRefPtr&lt;GCancellable&gt; m_cancellable;
</span><span class="cx">         GRefPtr&lt;GAsyncResult&gt; m_deferredResult;
</span><ins>+        GRefPtr&lt;GSource&gt; m_timeoutSource;
</ins><span class="cx">         char* m_buffer;
</span><span class="cx">         unsigned long m_bodySize;
</span><span class="cx">         unsigned long m_bodyDataSent;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworksoupResourceHandleSoupcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp (129635 => 129636)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp        2012-09-26 14:08:20 UTC (rev 129635)
+++ trunk/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp        2012-09-26 14:08:26 UTC (rev 129636)
</span><span class="lines">@@ -7,6 +7,7 @@
</span><span class="cx">  * Copyright (C) 2009 Christian Dywan &lt;christian@imendio.com&gt;
</span><span class="cx">  * Copyright (C) 2009, 2010, 2011 Igalia S.L.
</span><span class="cx">  * Copyright (C) 2009 John Kjellberg &lt;john.kjellberg@power.alstom.com&gt;
</span><ins>+ * Copyright (C) 2012 Intel Corporation
</ins><span class="cx">  *
</span><span class="cx">  * This library is free software; you can redistribute it and/or
</span><span class="cx">  * modify it under the terms of the GNU Library General Public
</span><span class="lines">@@ -71,6 +72,9 @@
</span><span class="cx"> 
</span><span class="cx"> #define READ_BUFFER_SIZE 8192
</span><span class="cx"> 
</span><ins>+// Use the same value as in NSURLError.h
+static const int gTimeoutError = -1001;
+
</ins><span class="cx"> static bool loadingSynchronousRequest = false;
</span><span class="cx"> 
</span><span class="cx"> class WebCoreSynchronousLoader : public ResourceHandleClient {
</span><span class="lines">@@ -201,6 +205,7 @@
</span><span class="cx"> static void sendRequestCallback(GObject*, GAsyncResult*, gpointer);
</span><span class="cx"> static void readCallback(GObject*, GAsyncResult*, gpointer);
</span><span class="cx"> static void closeCallback(GObject*, GAsyncResult*, gpointer);
</span><ins>+static gboolean requestTimeoutCallback(void*);
</ins><span class="cx"> static bool startNonHTTPRequest(ResourceHandle*, KURL);
</span><span class="cx"> #if ENABLE(WEB_TIMING)
</span><span class="cx"> static int  milisecondsSinceRequest(double requestTime);
</span><span class="lines">@@ -379,6 +384,11 @@
</span><span class="cx">         d-&gt;m_buffer = 0;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    if (d-&gt;m_timeoutSource) {
+        g_source_destroy(d-&gt;m_timeoutSource.get());
+        d-&gt;m_timeoutSource.clear();
+    }
+
</ins><span class="cx">     if (!isDestroying)
</span><span class="cx">         handle-&gt;deref();
</span><span class="cx"> }
</span><span class="lines">@@ -754,6 +764,10 @@
</span><span class="cx"> #if ENABLE(WEB_TIMING)
</span><span class="cx">         d-&gt;m_response.resourceLoadTiming()-&gt;requestTime = monotonicallyIncreasingTime();
</span><span class="cx"> #endif
</span><ins>+        if (d-&gt;m_firstRequest.timeoutInterval() &gt; 0) {
+            // soup_add_timeout returns a GSource* whose only reference is owned by the context. We need to have our own reference to it, hence not using adoptRef.
+            d-&gt;m_timeoutSource = soup_add_timeout(g_main_context_get_thread_default(), d-&gt;m_firstRequest.timeoutInterval() * 1000, requestTimeoutCallback, handle);
+        }
</ins><span class="cx">         d-&gt;m_cancellable = adoptGRef(g_cancellable_new());
</span><span class="cx">         soup_request_send_async(d-&gt;m_soupRequest.get(), d-&gt;m_cancellable.get(), sendRequestCallback, handle);
</span><span class="cx">     }
</span><span class="lines">@@ -839,9 +853,12 @@
</span><span class="cx">     if (d-&gt;m_cancelled)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    // We only need to take action here to UN-defer loading.
-    if (defersLoading)
</del><ins>+    // Except when canceling a possible timeout timer, we only need to take action here to UN-defer loading.
+    if (defersLoading) {
+        g_source_destroy(d-&gt;m_timeoutSource.get());
+        d-&gt;m_timeoutSource.clear();
</ins><span class="cx">         return;
</span><ins>+    }
</ins><span class="cx"> 
</span><span class="cx">     // We need to check for d-&gt;m_soupRequest because the request may
</span><span class="cx">     // have raised a failure (for example invalid URLs). We cannot
</span><span class="lines">@@ -853,6 +870,10 @@
</span><span class="cx">             d-&gt;m_response.resourceLoadTiming()-&gt;requestTime = monotonicallyIncreasingTime();
</span><span class="cx"> #endif
</span><span class="cx">         d-&gt;m_cancellable = adoptGRef(g_cancellable_new());
</span><ins>+        if (d-&gt;m_firstRequest.timeoutInterval() &gt; 0) {
+            // soup_add_timeout returns a GSource* whose only reference is owned by the context. We need to have our own reference to it, hence not using adoptRef.
+            d-&gt;m_timeoutSource = soup_add_timeout(g_main_context_get_thread_default(), d-&gt;m_firstRequest.timeoutInterval() * 1000, requestTimeoutCallback, this);
+        }
</ins><span class="cx">         soup_request_send_async(d-&gt;m_soupRequest.get(), d-&gt;m_cancellable.get(), sendRequestCallback, this);
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="lines">@@ -973,6 +994,20 @@
</span><span class="cx">                               d-&gt;m_cancellable.get(), readCallback, handle.get());
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static gboolean requestTimeoutCallback(gpointer data)
+{
+    RefPtr&lt;ResourceHandle&gt; handle = static_cast&lt;ResourceHandle*&gt;(data);
+    ResourceHandleInternal* d = handle-&gt;getInternal();
+    ResourceHandleClient* client = handle-&gt;client();
+
+    ResourceError timeoutError(&quot;WebKitNetworkError&quot;, gTimeoutError, d-&gt;m_firstRequest.url().string(), &quot;Request timed out&quot;);
+    timeoutError.setIsTimeout(true);
+    client-&gt;didFail(handle.get(), timeoutError);
+    cleanupSoupRequestOperation(handle.get());
+
+    return FALSE;
+}
+
</ins><span class="cx"> static bool startNonHTTPRequest(ResourceHandle* handle, KURL url)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(handle);
</span><span class="lines">@@ -1001,6 +1036,10 @@
</span><span class="cx">     // Send the request only if it's not been explicitly deferred.
</span><span class="cx">     if (!d-&gt;m_defersLoading) {
</span><span class="cx">         d-&gt;m_cancellable = adoptGRef(g_cancellable_new());
</span><ins>+        if (d-&gt;m_firstRequest.timeoutInterval() &gt; 0) {
+            // soup_add_timeout returns a GSource* whose only reference is owned by the context. We need to have our own reference to it, hence not using adoptRef.
+            d-&gt;m_timeoutSource = soup_add_timeout(g_main_context_get_thread_default(), d-&gt;m_firstRequest.timeoutInterval() * 1000, requestTimeoutCallback, handle);
+        }
</ins><span class="cx">         soup_request_send_async(d-&gt;m_soupRequest.get(), d-&gt;m_cancellable.get(), sendRequestCallback, handle);
</span><span class="cx">     }
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>