<!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>[214114] 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/214114">214114</a></dd>
<dt>Author</dt> <dd>achristensen@apple.com</dd>
<dt>Date</dt> <dd>2017-03-17 13:30:37 -0700 (Fri, 17 Mar 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>Make SocketStreamHandle virtual functions asynchronous
https://bugs.webkit.org/show_bug.cgi?id=169818

Reviewed by Andy Estes.

No change in behavior.  Instead of returning immediately, call a completion handler.
This is in preparation for making them truly asynchronous.

I still need to be able to synchronously get the number of buffered bytes, but the
buffer itself will soon be in the NetworkProcess with a new subclass of SocketStreamHandle
that messages across IPC.  The number of buffered bytes will still be stored in the WebProcess,
and when it updates, the message from SocketStreamHandleClient::didUpdateBufferedAmount will update it.

* CMakeLists.txt:
* WebCore.xcodeproj/project.pbxproj:
* platform/network/SocketStreamHandle.cpp:
(WebCore::SocketStreamHandle::send):
(WebCore::SocketStreamHandle::close):
(WebCore::SocketStreamHandle::sendPendingData): Deleted.
* platform/network/SocketStreamHandle.h:
(WebCore::SocketStreamHandle::bufferedAmount): Deleted.
* platform/network/SocketStreamHandleImpl.cpp: Added.
(WebCore::SocketStreamHandleImpl::platformSend):
(WebCore::SocketStreamHandleImpl::sendPendingData):
(WebCore::SocketStreamHandleImpl::bufferedAmount):
m_buffer was moved from SocketStreamHandle to SocketStreamHandleImpl, so some of the logic must move with it.
I moved as much logic that was shared in the superclass to a new shared location for code shared among the subclass implementations.
* platform/network/cf/SocketStreamHandleImpl.h:
* platform/network/cf/SocketStreamHandleImplCFNet.cpp:
(WebCore::SocketStreamHandleImpl::platformSendInternal):
(WebCore::SocketStreamHandleImpl::platformSend): Deleted.
* platform/network/curl/SocketStreamHandleImpl.h:
* platform/network/curl/SocketStreamHandleImplCurl.cpp:
(WebCore::SocketStreamHandleImpl::platformSendInternal):
(WebCore::SocketStreamHandleImpl::platformSend): Deleted.
* platform/network/soup/SocketStreamHandleImpl.h:
* platform/network/soup/SocketStreamHandleImplSoup.cpp:
(WebCore::SocketStreamHandleImpl::platformSendInternal):
(WebCore::SocketStreamHandleImpl::platformSend): Deleted.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreCMakeListstxt">trunk/Source/WebCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkSocketStreamHandlecpp">trunk/Source/WebCore/platform/network/SocketStreamHandle.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkSocketStreamHandleh">trunk/Source/WebCore/platform/network/SocketStreamHandle.h</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkcfSocketStreamHandleImplh">trunk/Source/WebCore/platform/network/cf/SocketStreamHandleImpl.h</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkcfSocketStreamHandleImplCFNetcpp">trunk/Source/WebCore/platform/network/cf/SocketStreamHandleImplCFNet.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkcurlSocketStreamHandleImplh">trunk/Source/WebCore/platform/network/curl/SocketStreamHandleImpl.h</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkcurlSocketStreamHandleImplCurlcpp">trunk/Source/WebCore/platform/network/curl/SocketStreamHandleImplCurl.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworksoupSocketStreamHandleImplh">trunk/Source/WebCore/platform/network/soup/SocketStreamHandleImpl.h</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworksoupSocketStreamHandleImplSoupcpp">trunk/Source/WebCore/platform/network/soup/SocketStreamHandleImplSoup.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreplatformnetworkSocketStreamHandleImplcpp">trunk/Source/WebCore/platform/network/SocketStreamHandleImpl.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/CMakeLists.txt (214113 => 214114)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/CMakeLists.txt        2017-03-17 19:52:49 UTC (rev 214113)
+++ trunk/Source/WebCore/CMakeLists.txt        2017-03-17 20:30:37 UTC (rev 214114)
</span><span class="lines">@@ -2423,6 +2423,7 @@
</span><span class="cx">     platform/network/ResourceRequestBase.cpp
</span><span class="cx">     platform/network/ResourceResponseBase.cpp
</span><span class="cx">     platform/network/SocketStreamHandle.cpp
</span><ins>+    platform/network/SocketStreamHandleImpl.cpp
</ins><span class="cx">     platform/network/SynchronousLoaderClient.cpp
</span><span class="cx"> 
</span><span class="cx">     platform/sql/SQLiteAuthorizer.cpp
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (214113 => 214114)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2017-03-17 19:52:49 UTC (rev 214113)
+++ trunk/Source/WebCore/ChangeLog        2017-03-17 20:30:37 UTC (rev 214114)
</span><span class="lines">@@ -1,3 +1,45 @@
</span><ins>+2017-03-17  Alex Christensen  &lt;achristensen@webkit.org&gt;
+
+        Make SocketStreamHandle virtual functions asynchronous
+        https://bugs.webkit.org/show_bug.cgi?id=169818
+
+        Reviewed by Andy Estes.
+
+        No change in behavior.  Instead of returning immediately, call a completion handler.
+        This is in preparation for making them truly asynchronous.
+
+        I still need to be able to synchronously get the number of buffered bytes, but the
+        buffer itself will soon be in the NetworkProcess with a new subclass of SocketStreamHandle
+        that messages across IPC.  The number of buffered bytes will still be stored in the WebProcess,
+        and when it updates, the message from SocketStreamHandleClient::didUpdateBufferedAmount will update it.
+
+        * CMakeLists.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * platform/network/SocketStreamHandle.cpp:
+        (WebCore::SocketStreamHandle::send):
+        (WebCore::SocketStreamHandle::close):
+        (WebCore::SocketStreamHandle::sendPendingData): Deleted.
+        * platform/network/SocketStreamHandle.h:
+        (WebCore::SocketStreamHandle::bufferedAmount): Deleted.
+        * platform/network/SocketStreamHandleImpl.cpp: Added.
+        (WebCore::SocketStreamHandleImpl::platformSend):
+        (WebCore::SocketStreamHandleImpl::sendPendingData):
+        (WebCore::SocketStreamHandleImpl::bufferedAmount):
+        m_buffer was moved from SocketStreamHandle to SocketStreamHandleImpl, so some of the logic must move with it.
+        I moved as much logic that was shared in the superclass to a new shared location for code shared among the subclass implementations.
+        * platform/network/cf/SocketStreamHandleImpl.h:
+        * platform/network/cf/SocketStreamHandleImplCFNet.cpp:
+        (WebCore::SocketStreamHandleImpl::platformSendInternal):
+        (WebCore::SocketStreamHandleImpl::platformSend): Deleted.
+        * platform/network/curl/SocketStreamHandleImpl.h:
+        * platform/network/curl/SocketStreamHandleImplCurl.cpp:
+        (WebCore::SocketStreamHandleImpl::platformSendInternal):
+        (WebCore::SocketStreamHandleImpl::platformSend): Deleted.
+        * platform/network/soup/SocketStreamHandleImpl.h:
+        * platform/network/soup/SocketStreamHandleImplSoup.cpp:
+        (WebCore::SocketStreamHandleImpl::platformSendInternal):
+        (WebCore::SocketStreamHandleImpl::platformSend): Deleted.
+
</ins><span class="cx"> 2017-03-17  Antti Koivisto  &lt;antti@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Add a reload policy where only expired subresources are revalidated
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (214113 => 214114)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2017-03-17 19:52:49 UTC (rev 214113)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2017-03-17 20:30:37 UTC (rev 214114)
</span><span class="lines">@@ -2647,6 +2647,7 @@
</span><span class="cx">                 5C4304B6191AEF46000E2BC0 /* JSEXTShaderTextureLOD.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C4304B4191AEF46000E2BC0 /* JSEXTShaderTextureLOD.h */; };
</span><span class="cx">                 5C5381B21D87D4B200E2EBE6 /* URLSearchParams.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5C5381B01D87D45700E2EBE6 /* URLSearchParams.cpp */; };
</span><span class="cx">                 5C5381B51D87E08700E2EBE6 /* JSURLSearchParams.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5C5381B31D87E08100E2EBE6 /* JSURLSearchParams.cpp */; };
</span><ins>+                5C668E651E7C6C4000D32B3B /* SocketStreamHandleImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5C668E641E7C6C3500D32B3B /* SocketStreamHandleImpl.cpp */; };
</ins><span class="cx">                 5C688AA11D380BF8000B54FA /* ThreadableWebSocketChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5C688AA01D380509000B54FA /* ThreadableWebSocketChannel.cpp */; };
</span><span class="cx">                 5C688AA31D3814BF000B54FA /* SocketProvider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5C688AA21D38126F000B54FA /* SocketProvider.cpp */; };
</span><span class="cx">                 5C6E65421D5CEFB900F7862E /* URLParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5C6E653F1D5CEDC900F7862E /* URLParser.cpp */; };
</span><span class="lines">@@ -10338,6 +10339,7 @@
</span><span class="cx">                 5C5381B11D87D45700E2EBE6 /* URLSearchParams.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = URLSearchParams.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 5C5381B31D87E08100E2EBE6 /* JSURLSearchParams.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSURLSearchParams.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 5C5381B41D87E08100E2EBE6 /* JSURLSearchParams.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSURLSearchParams.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                5C668E641E7C6C3500D32B3B /* SocketStreamHandleImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SocketStreamHandleImpl.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 5C688AA01D380509000B54FA /* ThreadableWebSocketChannel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ThreadableWebSocketChannel.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 5C688AA21D38126F000B54FA /* SocketProvider.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SocketProvider.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 5C6E653F1D5CEDC900F7862E /* URLParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = URLParser.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -18763,6 +18765,7 @@
</span><span class="cx">                                 510D4A30103165EE0049EA54 /* SocketStreamHandle.cpp */,
</span><span class="cx">                                 510D4A31103165EE0049EA54 /* SocketStreamHandle.h */,
</span><span class="cx">                                 510D4A32103165EE0049EA54 /* SocketStreamHandleClient.h */,
</span><ins>+                                5C668E641E7C6C3500D32B3B /* SocketStreamHandleImpl.cpp */,
</ins><span class="cx">                                 E180811016FCF42E00B80D07 /* SynchronousLoaderClient.cpp */,
</span><span class="cx">                                 E180811516FCF9CB00B80D07 /* SynchronousLoaderClient.h */,
</span><span class="cx">                         );
</span><span class="lines">@@ -30753,6 +30756,7 @@
</span><span class="cx">                                 2D5002F81B56D7810020AAF7 /* DOMPath.cpp in Sources */,
</span><span class="cx">                                 A9C6E4EB0D745E2B006442E9 /* DOMPlugin.cpp in Sources */,
</span><span class="cx">                                 A9C6E4EF0D745E38006442E9 /* DOMPluginArray.cpp in Sources */,
</span><ins>+                                5C668E651E7C6C4000D32B3B /* SocketStreamHandleImpl.cpp in Sources */,
</ins><span class="cx">                                 BC5A86840C33676000EEA649 /* DOMSelection.cpp in Sources */,
</span><span class="cx">                                 C55610F111A704EB00B82D27 /* DOMStringList.cpp in Sources */,
</span><span class="cx">                                 188604B30F2E654A000B6443 /* DOMTimer.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkSocketStreamHandlecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/SocketStreamHandle.cpp (214113 => 214114)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/SocketStreamHandle.cpp        2017-03-17 19:52:49 UTC (rev 214113)
+++ trunk/Source/WebCore/platform/network/SocketStreamHandle.cpp        2017-03-17 20:30:37 UTC (rev 214114)
</span><span class="lines">@@ -36,8 +36,6 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-const unsigned bufferSize = 100 * 1024 * 1024;
-
</del><span class="cx"> SocketStreamHandle::SocketStreamHandle(const URL&amp; url, SocketStreamHandleClient&amp; client)
</span><span class="cx">     : m_url(url)
</span><span class="cx">     , m_client(client)
</span><span class="lines">@@ -54,31 +52,7 @@
</span><span class="cx"> {
</span><span class="cx">     if (m_state == Connecting || m_state == Closing)
</span><span class="cx">         return completionHandler(false);
</span><del>-    if (!m_buffer.isEmpty()) {
-        if (m_buffer.size() + length &gt; bufferSize) {
-            // FIXME: report error to indicate that buffer has no more space.
-            return completionHandler(false);
-        }
-        m_buffer.append(data, length);
-        m_client.didUpdateBufferedAmount(static_cast&lt;SocketStreamHandle&amp;&gt;(*this), bufferedAmount());
-        return completionHandler(true);
-    }
-    size_t bytesWritten = 0;
-    if (m_state == Open) {
-        if (auto result = platformSend(data, length))
-            bytesWritten = result.value();
-        else
-            return completionHandler(false);
-    }
-    if (m_buffer.size() + length - bytesWritten &gt; bufferSize) {
-        // FIXME: report error to indicate that buffer has no more space.
-        return completionHandler(false);
-    }
-    if (bytesWritten &lt; length) {
-        m_buffer.append(data + bytesWritten, length - bytesWritten);
-        m_client.didUpdateBufferedAmount(static_cast&lt;SocketStreamHandle&amp;&gt;(*this), bufferedAmount());
-    }
-    return completionHandler(true);
</del><ins>+    platformSend(data, length, WTFMove(completionHandler));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void SocketStreamHandle::close()
</span><span class="lines">@@ -86,7 +60,7 @@
</span><span class="cx">     if (m_state == Closed)
</span><span class="cx">         return;
</span><span class="cx">     m_state = Closing;
</span><del>-    if (!m_buffer.isEmpty())
</del><ins>+    if (bufferedAmount())
</ins><span class="cx">         return;
</span><span class="cx">     disconnect();
</span><span class="cx"> }
</span><span class="lines">@@ -99,32 +73,4 @@
</span><span class="cx">     m_state = Closed;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool SocketStreamHandle::sendPendingData()
-{
-    if (m_state != Open &amp;&amp; m_state != Closing)
-        return false;
-    if (m_buffer.isEmpty()) {
-        if (m_state == Open)
-            return false;
-        if (m_state == Closing) {
-            disconnect();
-            return false;
-        }
-    }
-    bool pending;
-    do {
-        auto result = platformSend(m_buffer.firstBlockData(), m_buffer.firstBlockSize());
-        if (!result)
-            return false;
-        size_t bytesWritten = result.value();
-        if (!bytesWritten)
-            return false;
-        pending = bytesWritten != m_buffer.firstBlockSize();
-        ASSERT(m_buffer.size() - bytesWritten &lt;= bufferSize);
-        m_buffer.consume(bytesWritten);
-    } while (!pending &amp;&amp; !m_buffer.isEmpty());
-    m_client.didUpdateBufferedAmount(static_cast&lt;SocketStreamHandle&amp;&gt;(*this), bufferedAmount());
-    return true;
-}
-
</del><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkSocketStreamHandleh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/SocketStreamHandle.h (214113 => 214114)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/SocketStreamHandle.h        2017-03-17 19:52:49 UTC (rev 214113)
+++ trunk/Source/WebCore/platform/network/SocketStreamHandle.h        2017-03-17 20:30:37 UTC (rev 214114)
</span><span class="lines">@@ -32,7 +32,6 @@
</span><span class="cx"> #pragma once
</span><span class="cx"> 
</span><span class="cx"> #include &quot;URL.h&quot;
</span><del>-#include &lt;wtf/StreamBuffer.h&gt;
</del><span class="cx"> #include &lt;wtf/ThreadSafeRefCounted.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -48,18 +47,16 @@
</span><span class="cx">     void send(const char* data, size_t length, Function&lt;void(bool)&gt;);
</span><span class="cx">     void close(); // Disconnect after all data in buffer are sent.
</span><span class="cx">     void disconnect();
</span><del>-    size_t bufferedAmount() const { return m_buffer.size(); }
</del><ins>+    virtual size_t bufferedAmount() = 0;
</ins><span class="cx"> 
</span><span class="cx"> protected:
</span><span class="cx">     SocketStreamHandle(const URL&amp;, SocketStreamHandleClient&amp;);
</span><span class="cx"> 
</span><del>-    bool sendPendingData();
-    virtual std::optional&lt;size_t&gt; platformSend(const char* data, size_t length) = 0;
</del><ins>+    virtual void platformSend(const char* data, size_t length, Function&lt;void(bool)&gt;&amp;&amp;) = 0;
</ins><span class="cx">     virtual void platformClose() = 0;
</span><span class="cx"> 
</span><span class="cx">     URL m_url;
</span><span class="cx">     SocketStreamHandleClient&amp; m_client;
</span><del>-    StreamBuffer&lt;char, 1024 * 1024&gt; m_buffer;
</del><span class="cx">     SocketStreamState m_state;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkSocketStreamHandleImplcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/platform/network/SocketStreamHandleImpl.cpp (0 => 214114)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/SocketStreamHandleImpl.cpp                                (rev 0)
+++ trunk/Source/WebCore/platform/network/SocketStreamHandleImpl.cpp        2017-03-17 20:30:37 UTC (rev 214114)
</span><span class="lines">@@ -0,0 +1,96 @@
</span><ins>+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;SocketStreamHandleImpl.h&quot;
+
+#include &quot;SocketStreamHandleClient.h&quot;
+#include &lt;wtf/Function.h&gt;
+
+namespace WebCore {
+
+void SocketStreamHandleImpl::platformSend(const char* data, size_t length, Function&lt;void(bool)&gt;&amp;&amp; completionHandler)
+{
+    if (!m_buffer.isEmpty()) {
+        if (m_buffer.size() + length &gt; maxBufferSize) {
+            // FIXME: report error to indicate that buffer has no more space.
+            return completionHandler(false);
+        }
+        m_buffer.append(data, length);
+        m_client.didUpdateBufferedAmount(*this, bufferedAmount());
+        return completionHandler(true);
+    }
+    size_t bytesWritten = 0;
+    if (m_state == Open) {
+        if (auto result = platformSendInternal(data, length))
+            bytesWritten = result.value();
+        else
+            return completionHandler(false);
+    }
+    if (m_buffer.size() + length - bytesWritten &gt; maxBufferSize) {
+        // FIXME: report error to indicate that buffer has no more space.
+        return completionHandler(false);
+    }
+    if (bytesWritten &lt; length) {
+        m_buffer.append(data + bytesWritten, length - bytesWritten);
+        m_client.didUpdateBufferedAmount(static_cast&lt;SocketStreamHandle&amp;&gt;(*this), bufferedAmount());
+    }
+    return completionHandler(true);
+}
+
+bool SocketStreamHandleImpl::sendPendingData()
+{
+    if (m_state != Open &amp;&amp; m_state != Closing)
+        return false;
+    if (m_buffer.isEmpty()) {
+        if (m_state == Open)
+            return false;
+        if (m_state == Closing) {
+            disconnect();
+            return false;
+        }
+    }
+    bool pending;
+    do {
+        auto result = platformSendInternal(m_buffer.firstBlockData(), m_buffer.firstBlockSize());
+        if (!result)
+            return false;
+        size_t bytesWritten = result.value();
+        if (!bytesWritten)
+            return false;
+        pending = bytesWritten != m_buffer.firstBlockSize();
+        ASSERT(m_buffer.size() - bytesWritten &lt;= maxBufferSize);
+        m_buffer.consume(bytesWritten);
+    } while (!pending &amp;&amp; !m_buffer.isEmpty());
+    m_client.didUpdateBufferedAmount(static_cast&lt;SocketStreamHandle&amp;&gt;(*this), bufferedAmount());
+    return true;
+}
+
+size_t SocketStreamHandleImpl::bufferedAmount()
+{
+    return m_buffer.size();
+}
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkcfSocketStreamHandleImplh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/cf/SocketStreamHandleImpl.h (214113 => 214114)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/cf/SocketStreamHandleImpl.h        2017-03-17 19:52:49 UTC (rev 214113)
+++ trunk/Source/WebCore/platform/network/cf/SocketStreamHandleImpl.h        2017-03-17 20:30:37 UTC (rev 214114)
</span><span class="lines">@@ -34,6 +34,7 @@
</span><span class="cx"> #include &quot;SessionID.h&quot;
</span><span class="cx"> #include &quot;SocketStreamHandle.h&quot;
</span><span class="cx"> #include &lt;wtf/RetainPtr.h&gt;
</span><ins>+#include &lt;wtf/StreamBuffer.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> typedef struct __CFHTTPMessage* CFHTTPMessageRef;
</span><span class="cx"> 
</span><span class="lines">@@ -50,8 +51,11 @@
</span><span class="cx">     virtual ~SocketStreamHandleImpl();
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    std::optional&lt;size_t&gt; platformSend(const char* data, size_t length) final;
</del><ins>+    void platformSend(const char* data, size_t length, Function&lt;void(bool)&gt;&amp;&amp;) final;
</ins><span class="cx">     void platformClose() final;
</span><ins>+    size_t bufferedAmount() final;
+    std::optional&lt;size_t&gt; platformSendInternal(const char*, size_t);
+    bool sendPendingData();
</ins><span class="cx"> 
</span><span class="cx">     WEBCORE_EXPORT SocketStreamHandleImpl(const URL&amp;, SocketStreamHandleClient&amp;, SessionID, const String&amp; credentialPartition);
</span><span class="cx">     void createStreams();
</span><span class="lines">@@ -97,6 +101,9 @@
</span><span class="cx">     RetainPtr&lt;CFURLRef&gt; m_httpsURL; // ws(s): replaced with https:
</span><span class="cx">     SessionID m_sessionID;
</span><span class="cx">     String m_credentialPartition;
</span><ins>+    
+    StreamBuffer&lt;char, 1024 * 1024&gt; m_buffer;
+    static const unsigned maxBufferSize = 100 * 1024 * 1024;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkcfSocketStreamHandleImplCFNetcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/cf/SocketStreamHandleImplCFNet.cpp (214113 => 214114)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/cf/SocketStreamHandleImplCFNet.cpp        2017-03-17 19:52:49 UTC (rev 214113)
+++ trunk/Source/WebCore/platform/network/cf/SocketStreamHandleImplCFNet.cpp        2017-03-17 20:30:37 UTC (rev 214114)
</span><span class="lines">@@ -653,7 +653,7 @@
</span><span class="cx">     ASSERT(!m_pacRunLoopSource);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-std::optional&lt;size_t&gt; SocketStreamHandleImpl::platformSend(const char* data, size_t length)
</del><ins>+std::optional&lt;size_t&gt; SocketStreamHandleImpl::platformSendInternal(const char* data, size_t length)
</ins><span class="cx"> {
</span><span class="cx">     if (!CFWriteStreamCanAcceptBytes(m_writeStream.get()))
</span><span class="cx">         return std::nullopt;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkcurlSocketStreamHandleImplh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/curl/SocketStreamHandleImpl.h (214113 => 214114)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/curl/SocketStreamHandleImpl.h        2017-03-17 19:52:49 UTC (rev 214113)
+++ trunk/Source/WebCore/platform/network/curl/SocketStreamHandleImpl.h        2017-03-17 20:30:37 UTC (rev 214114)
</span><span class="lines">@@ -42,6 +42,7 @@
</span><span class="cx"> #include &lt;wtf/Deque.h&gt;
</span><span class="cx"> #include &lt;wtf/Lock.h&gt;
</span><span class="cx"> #include &lt;wtf/RefCounted.h&gt;
</span><ins>+#include &lt;wtf/StreamBuffer.h&gt;
</ins><span class="cx"> #include &lt;wtf/Threading.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -57,8 +58,11 @@
</span><span class="cx"> private:
</span><span class="cx">     SocketStreamHandleImpl(const URL&amp;, SocketStreamHandleClient&amp;);
</span><span class="cx"> 
</span><del>-    std::optional&lt;size_t&gt; platformSend(const char* data, size_t length) final;
</del><ins>+    void platformSend(const char* data, size_t length, Function&lt;void(bool)&gt;&amp;&amp;) final;
</ins><span class="cx">     void platformClose() final;
</span><ins>+    size_t bufferedAmount() final;
+    std::optional&lt;size_t&gt; platformSendInternal(const char*, size_t);
+    bool sendPendingData();
</ins><span class="cx"> 
</span><span class="cx">     bool readData(CURL*);
</span><span class="cx">     bool sendData(CURL*);
</span><span class="lines">@@ -94,6 +98,9 @@
</span><span class="cx">     Lock m_mutexReceive;
</span><span class="cx">     Deque&lt;SocketData&gt; m_sendData;
</span><span class="cx">     Deque&lt;SocketData&gt; m_receiveData;
</span><ins>+
+    StreamBuffer&lt;char, 1024 * 1024&gt; m_buffer;
+    static const unsigned maxBufferSize = 100 * 1024 * 1024;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkcurlSocketStreamHandleImplCurlcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/curl/SocketStreamHandleImplCurl.cpp (214113 => 214114)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/curl/SocketStreamHandleImplCurl.cpp        2017-03-17 19:52:49 UTC (rev 214113)
+++ trunk/Source/WebCore/platform/network/curl/SocketStreamHandleImplCurl.cpp        2017-03-17 20:30:37 UTC (rev 214114)
</span><span class="lines">@@ -66,7 +66,7 @@
</span><span class="cx">     ASSERT(!m_workerThread);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-std::optional&lt;size_t&gt; SocketStreamHandleImpl::platformSend(const char* data, size_t length)
</del><ins>+std::optional&lt;size_t&gt; SocketStreamHandleImpl::platformSendInternal(const char* data, size_t length)
</ins><span class="cx"> {
</span><span class="cx">     LOG(Network, &quot;SocketStreamHandle %p platformSend&quot;, this);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworksoupSocketStreamHandleImplh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/soup/SocketStreamHandleImpl.h (214113 => 214114)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/soup/SocketStreamHandleImpl.h        2017-03-17 19:52:49 UTC (rev 214113)
+++ trunk/Source/WebCore/platform/network/soup/SocketStreamHandleImpl.h        2017-03-17 20:30:37 UTC (rev 214114)
</span><span class="lines">@@ -38,6 +38,7 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;SessionID.h&quot;
</span><span class="cx"> #include &lt;wtf/RefCounted.h&gt;
</span><ins>+#include &lt;wtf/StreamBuffer.h&gt;
</ins><span class="cx"> #include &lt;wtf/glib/GRefPtr.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -55,8 +56,11 @@
</span><span class="cx"> private:
</span><span class="cx">     SocketStreamHandleImpl(const URL&amp;, SocketStreamHandleClient&amp;);
</span><span class="cx"> 
</span><del>-    std::optional&lt;size_t&gt; platformSend(const char* data, size_t length) final;
</del><ins>+    void platformSend(const char* data, size_t length, Function&lt;void(bool)&gt;&amp;&amp;) final;
</ins><span class="cx">     void platformClose() final;
</span><ins>+    size_t bufferedAmount() final;
+    std::optional&lt;size_t&gt; platformSendInternal(const char*, size_t);
+    bool sendPendingData();
</ins><span class="cx"> 
</span><span class="cx">     void beginWaitingForSocketWritability();
</span><span class="cx">     void stopWaitingForSocketWritability();
</span><span class="lines">@@ -76,6 +80,9 @@
</span><span class="cx">     GRefPtr&lt;GSource&gt; m_writeReadySource;
</span><span class="cx">     GRefPtr&lt;GCancellable&gt; m_cancellable;
</span><span class="cx">     std::unique_ptr&lt;char[]&gt; m_readBuffer;
</span><ins>+
+    StreamBuffer&lt;char, 1024 * 1024&gt; m_buffer;
+    static const unsigned maxBufferSize = 100 * 1024 * 1024;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworksoupSocketStreamHandleImplSoupcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/soup/SocketStreamHandleImplSoup.cpp (214113 => 214114)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/soup/SocketStreamHandleImplSoup.cpp        2017-03-17 19:52:49 UTC (rev 214113)
+++ trunk/Source/WebCore/platform/network/soup/SocketStreamHandleImplSoup.cpp        2017-03-17 20:30:37 UTC (rev 214114)
</span><span class="lines">@@ -190,7 +190,7 @@
</span><span class="cx">     sendPendingData();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-std::optional&lt;size_t&gt; SocketStreamHandleImpl::platformSend(const char* data, size_t length)
</del><ins>+std::optional&lt;size_t&gt; SocketStreamHandleImpl::platformSendInternal(const char* data, size_t length)
</ins><span class="cx"> {
</span><span class="cx">     LOG(Network, &quot;SocketStreamHandle %p platformSend&quot;, this);
</span><span class="cx">     if (!m_outputStream || !data)
</span></span></pre>
</div>
</div>

</body>
</html>