<!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>[207156] trunk</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/207156">207156</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2016-10-11 12:35:36 -0700 (Tue, 11 Oct 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Add SynchronizedFixedQueue class
https://bugs.webkit.org/show_bug.cgi?id=162478

Patch by Said Abou-Hallawa &lt;sabouhallawa@apple.com&gt; on 2016-10-11
Reviewed by Geoffrey Garen.

Source/WTF:

This class represents a simple producer/consumer worker. It facilitates
synchronizing enqueuing to and dequeuing from a fixed size-queue. It uses
a single lock and a single condition to synchronize all its members among
the working threads. This means a single thread is active at any time and
and the other threads are blocked waiting for the lock to be released. Or
they are sleeping waiting for the condition to be satisfied.

* WTF.xcodeproj/project.pbxproj:
* wtf/SynchronizedFixedQueue.h: Added.
(WTF::SynchronizedFixedQueue::SynchronizedFixedQueue):
(WTF::SynchronizedFixedQueue::open): Restore the queue to its original state.
(WTF::SynchronizedFixedQueue::close): Wake all the sleeping threads with a closing state.
(WTF::SynchronizedFixedQueue::isOpen): Does the queue accept new items?
(WTF::SynchronizedFixedQueue::enqueue): Enqueue an item into the queue.
(WTF::SynchronizedFixedQueue::dequeue): Dequeue an item form the queue.

Tools:

Add a new test for SynchronizedFixedQueue. The test defines a new class
called ToUpperConverter which converts strings from lower case to upper
case. It creates two threads : (1) produce thread and (2) consume thread.
Here is what each thread does:

1. Main threads: Enqueues lower case strings into m_lowerQueue.
2. Produce thread: Dequeues lower case strings from m_lowerQueue and
   enqueue their upper case strings in the m_upperQueue.
3. Consume thread: Dequeues upper case strings from m_upperQueue.

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WTF/SynchronizedFixedQueue.cpp: Added.
(TestWebKitAPI::textItem): A helper function which returns a lower case string given an index.
(TestWebKitAPI::toUpper): A helper function which Returns the upper case of a string.
(TestWebKitAPI::ToUpperConverter::ToUpperConverter):
(TestWebKitAPI::ToUpperConverter::produceQueue): Returns a workQueue for the produce thread.
(TestWebKitAPI::ToUpperConverter::consumeQueue): Returns a workQueue for the consume thread.
(TestWebKitAPI::ToUpperConverter::startProducing): Creates a thread for the producer.
(TestWebKitAPI::ToUpperConverter::startConsuming): Creates a thread for the consumer.
(TestWebKitAPI::ToUpperConverter::start): Starts both the producer and the consumer threads.
(TestWebKitAPI::ToUpperConverter::stopProducing): Terminates the producer thread.
(TestWebKitAPI::ToUpperConverter::stopConsuming): Terminates the consumer thread.
(TestWebKitAPI::ToUpperConverter::stop): Terminates both the producer and the consumer threads.
(TestWebKitAPI::ToUpperConverter::enqueueLower): Adds a lower case string to the m_lowerQueue on the main thread.
(TestWebKitAPI::ToUpperConverter::isProducing): Returns whether the producing thread is active.
(TestWebKitAPI::ToUpperConverter::isConsuming): Returns whether the consuming thread is active.
(TestWebKitAPI::ToUpperConverter::produceCount): Returns the number of produced elements.
(TestWebKitAPI::ToUpperConverter::consumeCount): Returns the number of consumed elements.
(TestWebKitAPI::TEST):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWTFChangeLog">trunk/Source/WTF/ChangeLog</a></li>
<li><a href="#trunkSourceWTFWTFxcodeprojprojectpbxproj">trunk/Source/WTF/WTF.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsTestWebKitAPITestWebKitAPIxcodeprojprojectpbxproj">trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWTFwtfSynchronizedFixedQueueh">trunk/Source/WTF/wtf/SynchronizedFixedQueue.h</a></li>
<li><a href="#trunkToolsTestWebKitAPITestsWTFSynchronizedFixedQueuecpp">trunk/Tools/TestWebKitAPI/Tests/WTF/SynchronizedFixedQueue.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/ChangeLog (207155 => 207156)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/ChangeLog        2016-10-11 19:29:47 UTC (rev 207155)
+++ trunk/Source/WTF/ChangeLog        2016-10-11 19:35:36 UTC (rev 207156)
</span><span class="lines">@@ -1,3 +1,26 @@
</span><ins>+2016-10-11  Said Abou-Hallawa  &lt;sabouhallawa@apple.com&gt;
+
+        Add SynchronizedFixedQueue class
+        https://bugs.webkit.org/show_bug.cgi?id=162478
+
+        Reviewed by Geoffrey Garen.
+
+        This class represents a simple producer/consumer worker. It facilitates
+        synchronizing enqueuing to and dequeuing from a fixed size-queue. It uses
+        a single lock and a single condition to synchronize all its members among
+        the working threads. This means a single thread is active at any time and
+        and the other threads are blocked waiting for the lock to be released. Or
+        they are sleeping waiting for the condition to be satisfied.
+
+        * WTF.xcodeproj/project.pbxproj:
+        * wtf/SynchronizedFixedQueue.h: Added.
+        (WTF::SynchronizedFixedQueue::SynchronizedFixedQueue):
+        (WTF::SynchronizedFixedQueue::open): Restore the queue to its original state.
+        (WTF::SynchronizedFixedQueue::close): Wake all the sleeping threads with a closing state.
+        (WTF::SynchronizedFixedQueue::isOpen): Does the queue accept new items?
+        (WTF::SynchronizedFixedQueue::enqueue): Enqueue an item into the queue.
+        (WTF::SynchronizedFixedQueue::dequeue): Dequeue an item form the queue.
+
</ins><span class="cx"> 2016-10-11  Alex Christensen  &lt;achristensen@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Remove dead networking code
</span></span></pre></div>
<a id="trunkSourceWTFWTFxcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/WTF.xcodeproj/project.pbxproj (207155 => 207156)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/WTF.xcodeproj/project.pbxproj        2016-10-11 19:29:47 UTC (rev 207155)
+++ trunk/Source/WTF/WTF.xcodeproj/project.pbxproj        2016-10-11 19:35:36 UTC (rev 207156)
</span><span class="lines">@@ -119,6 +119,7 @@
</span><span class="cx">                 515F79561CFD3A6900CCED93 /* CrossThreadQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 515F79551CFD3A6900CCED93 /* CrossThreadQueue.h */; };
</span><span class="cx">                 539EB0631D55284200C82EF7 /* LEBDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 539EB0621D55284200C82EF7 /* LEBDecoder.h */; };
</span><span class="cx">                 553071CA1C40427200384898 /* TinyLRUCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 553071C91C40427200384898 /* TinyLRUCache.h */; };
</span><ins>+                5597F82F1D94B9970066BC21 /* SynchronizedFixedQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 5597F82C1D94B9970066BC21 /* SynchronizedFixedQueue.h */; };
</ins><span class="cx">                 5C7C88D41D0A3A0A009D2F6D /* UniqueRef.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C7C88D31D0A3A0A009D2F6D /* UniqueRef.h */; };
</span><span class="cx">                 70A993FE1AD7151300FA615B /* SymbolRegistry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 70A993FC1AD7151300FA615B /* SymbolRegistry.cpp */; };
</span><span class="cx">                 70A993FF1AD7151300FA615B /* SymbolRegistry.h in Headers */ = {isa = PBXBuildFile; fileRef = 70A993FD1AD7151300FA615B /* SymbolRegistry.h */; };
</span><span class="lines">@@ -463,6 +464,7 @@
</span><span class="cx">                 515F79551CFD3A6900CCED93 /* CrossThreadQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CrossThreadQueue.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 539EB0621D55284200C82EF7 /* LEBDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LEBDecoder.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 553071C91C40427200384898 /* TinyLRUCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TinyLRUCache.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                5597F82C1D94B9970066BC21 /* SynchronizedFixedQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SynchronizedFixedQueue.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 5B43383A5D0B463C9433D933 /* IndexMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IndexMap.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 5C7C88D31D0A3A0A009D2F6D /* UniqueRef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UniqueRef.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 5D247B6214689B8600E78B76 /* libWTF.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libWTF.a; sourceTree = BUILT_PRODUCTS_DIR; };
</span><span class="lines">@@ -1023,6 +1025,7 @@
</span><span class="cx">                                 A748745117A0BDAE00FA04CB /* StringHashDumpContext.h */,
</span><span class="cx">                                 0FDDBFA51666DFA300C55FEF /* StringPrintStream.cpp */,
</span><span class="cx">                                 0FDDBFA61666DFA300C55FEF /* StringPrintStream.h */,
</span><ins>+                                5597F82C1D94B9970066BC21 /* SynchronizedFixedQueue.h */,
</ins><span class="cx">                                 0FB317C31C488001007E395A /* SystemTracing.h */,
</span><span class="cx">                                 A8A4731A151A825B004123FF /* TemporaryChange.h */,
</span><span class="cx">                                 A8A4732F151A825B004123FF /* ThreadFunctionInvocation.h */,
</span><span class="lines">@@ -1407,6 +1410,7 @@
</span><span class="cx">                                 C4F8A93719C65EB400B2B15D /* Stopwatch.h in Headers */,
</span><span class="cx">                                 1A6BB769162F300500DD16DB /* StreamBuffer.h in Headers */,
</span><span class="cx">                                 A8A4743B151A825B004123FF /* StringBuffer.h in Headers */,
</span><ins>+                                5597F82F1D94B9970066BC21 /* SynchronizedFixedQueue.h in Headers */,
</ins><span class="cx">                                 A8A4743D151A825B004123FF /* StringBuilder.h in Headers */,
</span><span class="cx">                                 430B47891AAAAC1A001223DA /* StringCommon.h in Headers */,
</span><span class="cx">                                 A8A4743E151A825B004123FF /* StringConcatenate.h in Headers */,
</span></span></pre></div>
<a id="trunkSourceWTFwtfSynchronizedFixedQueueh"></a>
<div class="addfile"><h4>Added: trunk/Source/WTF/wtf/SynchronizedFixedQueue.h (0 => 207156)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/SynchronizedFixedQueue.h                                (rev 0)
+++ trunk/Source/WTF/wtf/SynchronizedFixedQueue.h        2016-10-11 19:35:36 UTC (rev 207156)
</span><span class="lines">@@ -0,0 +1,121 @@
</span><ins>+/*
+ * Copyright (C) 2016 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. ``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
+ * 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.
+ */
+
+#pragma once
+
+#include &lt;wtf/Condition.h&gt;
+#include &lt;wtf/Deque.h&gt;
+#include &lt;wtf/HashSet.h&gt;
+#include &lt;wtf/Lock.h&gt;
+#include &lt;wtf/Locker.h&gt;
+
+namespace WTF {
+
+template&lt;typename T, size_t BufferSize&gt;
+class SynchronizedFixedQueue {
+public:
+    SynchronizedFixedQueue()
+    {
+        static_assert(!((BufferSize - 1) &amp; BufferSize), &quot;BufferSize must be power of 2.&quot;);
+    }
+    
+    void open()
+    {
+        LockHolder lockHolder(m_mutex);
+        if (m_open)
+            return;
+
+        // Restore the queue to its original state.
+        m_open = true;
+        m_queue.clear();
+    }
+    
+    void close()
+    {
+        LockHolder lockHolder(m_mutex);
+        if (!m_open)
+            return;
+
+        // Wake all the sleeping threads up with a closing state.
+        m_open = false;
+        m_condition.notifyAll();
+    }
+    
+    bool isOpen()
+    {
+        LockHolder lockHolder(m_mutex);
+        return m_open;
+    }
+
+    bool enqueue(const T&amp; value)
+    {
+        LockHolder lockHolder(m_mutex);
+
+        // Wait for an empty place to be available in the queue.
+        m_condition.wait(m_mutex, [this]() { return !m_open || m_queue.size() &lt; BufferSize; });
+        
+        // The queue is closing, exit immediately.
+        if (!m_open)
+            return false;
+        
+        // Add the item in the queue.
+        m_queue.append(value);
+
+        // Notify the other threads that an item was added to the queue.
+        m_condition.notifyAll();
+        return true;
+    }
+    
+    bool dequeue(T&amp; value)
+    {
+        LockHolder lockHolder(m_mutex);
+        
+        // Wait for an item to be added.
+        m_condition.wait(m_mutex, [this]() { return !m_open || m_queue.size(); });
+
+        // The queue is closing, exit immediately.
+        if (!m_open)
+            return false;
+
+        // Get a copy from m_queue.first and then remove it.
+        value = m_queue.first();
+        m_queue.removeFirst();
+
+        // Notify the other threads that an item was removed from the queue.
+        m_condition.notifyAll();
+        return true;
+    }
+
+private:
+    Lock m_mutex;
+    Condition m_condition;
+
+    bool m_open { true };
+    Deque&lt;T, BufferSize&gt; m_queue;
+};
+
+}
+
+using WTF::SynchronizedFixedQueue;
</ins></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (207155 => 207156)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog        2016-10-11 19:29:47 UTC (rev 207155)
+++ trunk/Tools/ChangeLog        2016-10-11 19:35:36 UTC (rev 207156)
</span><span class="lines">@@ -1,3 +1,40 @@
</span><ins>+2016-10-11  Said Abou-Hallawa  &lt;sabouhallawa@apple.com&gt;
+
+        Add SynchronizedFixedQueue class
+        https://bugs.webkit.org/show_bug.cgi?id=162478
+
+        Reviewed by Geoffrey Garen.
+
+        Add a new test for SynchronizedFixedQueue. The test defines a new class
+        called ToUpperConverter which converts strings from lower case to upper
+        case. It creates two threads : (1) produce thread and (2) consume thread.
+        Here is what each thread does:
+
+        1. Main threads: Enqueues lower case strings into m_lowerQueue.
+        2. Produce thread: Dequeues lower case strings from m_lowerQueue and 
+           enqueue their upper case strings in the m_upperQueue.
+        3. Consume thread: Dequeues upper case strings from m_upperQueue.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WTF/SynchronizedFixedQueue.cpp: Added.
+        (TestWebKitAPI::textItem): A helper function which returns a lower case string given an index.
+        (TestWebKitAPI::toUpper): A helper function which Returns the upper case of a string.
+        (TestWebKitAPI::ToUpperConverter::ToUpperConverter):
+        (TestWebKitAPI::ToUpperConverter::produceQueue): Returns a workQueue for the produce thread.
+        (TestWebKitAPI::ToUpperConverter::consumeQueue): Returns a workQueue for the consume thread.
+        (TestWebKitAPI::ToUpperConverter::startProducing): Creates a thread for the producer.
+        (TestWebKitAPI::ToUpperConverter::startConsuming): Creates a thread for the consumer.
+        (TestWebKitAPI::ToUpperConverter::start): Starts both the producer and the consumer threads.
+        (TestWebKitAPI::ToUpperConverter::stopProducing): Terminates the producer thread.
+        (TestWebKitAPI::ToUpperConverter::stopConsuming): Terminates the consumer thread.
+        (TestWebKitAPI::ToUpperConverter::stop): Terminates both the producer and the consumer threads.
+        (TestWebKitAPI::ToUpperConverter::enqueueLower): Adds a lower case string to the m_lowerQueue on the main thread.
+        (TestWebKitAPI::ToUpperConverter::isProducing): Returns whether the producing thread is active.
+        (TestWebKitAPI::ToUpperConverter::isConsuming): Returns whether the consuming thread is active.
+        (TestWebKitAPI::ToUpperConverter::produceCount): Returns the number of produced elements.
+        (TestWebKitAPI::ToUpperConverter::consumeCount): Returns the number of consumed elements.
+        (TestWebKitAPI::TEST):
+
</ins><span class="cx"> 2016-10-11  Megan Gardner  &lt;megan_gardner@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Extend event stream to include interpolated events and add a force press test that uses that interpolation
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPITestWebKitAPIxcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (207155 => 207156)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj        2016-10-11 19:29:47 UTC (rev 207155)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj        2016-10-11 19:35:36 UTC (rev 207156)
</span><span class="lines">@@ -140,6 +140,7 @@
</span><span class="cx">                 52E5CE4914D21EAB003B2BD8 /* ParentFrame_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52E5CE4814D21EAB003B2BD8 /* ParentFrame_Bundle.cpp */; };
</span><span class="cx">                 536770341CC8022800D425B1 /* WebScriptObjectDescription.mm in Sources */ = {isa = PBXBuildFile; fileRef = 536770331CC8022800D425B1 /* WebScriptObjectDescription.mm */; };
</span><span class="cx">                 536770361CC81B6100D425B1 /* WebScriptObjectDescription.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 536770351CC812F900D425B1 /* WebScriptObjectDescription.html */; };
</span><ins>+                5597F8361D9596C80066BC21 /* SynchronizedFixedQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5597F8341D9596C80066BC21 /* SynchronizedFixedQueue.cpp */; };
</ins><span class="cx">                 5714ECB91CA8B5B000051AC8 /* DownloadRequestOriginalURL.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 5714ECB81CA8B58800051AC8 /* DownloadRequestOriginalURL.html */; };
</span><span class="cx">                 5714ECBB1CA8BFE400051AC8 /* DownloadRequestOriginalURLFrame.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 5714ECBA1CA8BFD100051AC8 /* DownloadRequestOriginalURLFrame.html */; };
</span><span class="cx">                 5714ECBD1CA8C22A00051AC8 /* DownloadRequestOriginalURL2.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 5714ECBC1CA8C21800051AC8 /* DownloadRequestOriginalURL2.html */; };
</span><span class="lines">@@ -916,6 +917,7 @@
</span><span class="cx">                 52E5CE4814D21EAB003B2BD8 /* ParentFrame_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParentFrame_Bundle.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 536770331CC8022800D425B1 /* WebScriptObjectDescription.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebScriptObjectDescription.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 536770351CC812F900D425B1 /* WebScriptObjectDescription.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = WebScriptObjectDescription.html; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                5597F8341D9596C80066BC21 /* SynchronizedFixedQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SynchronizedFixedQueue.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 5714ECB81CA8B58800051AC8 /* DownloadRequestOriginalURL.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = DownloadRequestOriginalURL.html; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 5714ECBA1CA8BFD100051AC8 /* DownloadRequestOriginalURLFrame.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = DownloadRequestOriginalURLFrame.html; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 5714ECBC1CA8C21800051AC8 /* DownloadRequestOriginalURL2.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = DownloadRequestOriginalURL2.html; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -1795,6 +1797,7 @@
</span><span class="cx">                                 26F1B44315CA434F00D1E4BF /* StringImpl.cpp */,
</span><span class="cx">                                 C01363C713C3997300EF3964 /* StringOperators.cpp */,
</span><span class="cx">                                 7C74D42D188228F300E5ED57 /* StringView.cpp */,
</span><ins>+                                5597F8341D9596C80066BC21 /* SynchronizedFixedQueue.cpp */,
</ins><span class="cx">                                 0BCD85691485C98B00EA2003 /* TemporaryChange.cpp */,
</span><span class="cx">                                 5C5E633D1D0B67940085A025 /* UniqueRef.cpp */,
</span><span class="cx">                                 7CD0D5AA1D5534DE000CC9E1 /* Variant.cpp */,
</span><span class="lines">@@ -2289,6 +2292,7 @@
</span><span class="cx">                                 7C83DF361D0A590C00FEBCF3 /* StringHasher.cpp in Sources */,
</span><span class="cx">                                 7C83DF371D0A590C00FEBCF3 /* StringImpl.cpp in Sources */,
</span><span class="cx">                                 7C83DF381D0A590C00FEBCF3 /* StringOperators.cpp in Sources */,
</span><ins>+                                5597F8361D9596C80066BC21 /* SynchronizedFixedQueue.cpp in Sources */,
</ins><span class="cx">                                 7C83DF3A1D0A590C00FEBCF3 /* StringView.cpp in Sources */,
</span><span class="cx">                                 7C83DF3D1D0A590C00FEBCF3 /* TemporaryChange.cpp in Sources */,
</span><span class="cx">                                 7C83DF401D0A590C00FEBCF3 /* TestsController.cpp in Sources */,
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPITestsWTFSynchronizedFixedQueuecpp"></a>
<div class="addfile"><h4>Added: trunk/Tools/TestWebKitAPI/Tests/WTF/SynchronizedFixedQueue.cpp (0 => 207156)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/Tests/WTF/SynchronizedFixedQueue.cpp                                (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WTF/SynchronizedFixedQueue.cpp        2016-10-11 19:35:36 UTC (rev 207156)
</span><span class="lines">@@ -0,0 +1,229 @@
</span><ins>+/*
+ * Copyright (C) 2016 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 &lt;chrono&gt;
+#include &lt;thread&gt;
+
+#include &lt;wtf/ASCIICType.h&gt;
+#include &lt;wtf/SynchronizedFixedQueue.h&gt;
+#include &lt;wtf/WorkQueue.h&gt;
+#include &lt;wtf/text/CString.h&gt;
+#include &lt;wtf/threads/BinarySemaphore.h&gt;
+
+namespace TestWebKitAPI {
+
+static char const* textItem(size_t index)
+{
+    static char const* items[] = { &quot;first&quot;, &quot;second&quot;, &quot;third&quot;, &quot;fourth&quot;, &quot;fifth&quot;, &quot;sixth&quot; };
+    return index &lt; sizeof(items) / sizeof(items[0]) ? items[index] : nullptr;
+}
+
+static CString toUpper(const CString&amp; lower)
+{
+    CString upper = lower;
+
+    for (char* buffer = upper.mutableData(); *buffer; ++buffer)
+        *buffer = toASCIIUpper(*buffer);
+
+    return upper;
+}
+
+template &lt;size_t BufferSize&gt;
+class ToUpperConverter {
+public:
+    ToUpperConverter()
+    {
+    }
+
+    WorkQueue* produceQueue()
+    {
+        if (!m_produceQueue)
+            m_produceQueue = WorkQueue::create(&quot;org.webkit.Produce&quot;);
+        return m_produceQueue.get();
+    }
+
+    WorkQueue* consumeQueue()
+    {
+        if (!m_consumeQueue)
+            m_consumeQueue = WorkQueue::create(&quot;org.webkit.Consume&quot;);
+        return m_consumeQueue.get();
+    }
+
+    void startProducing()
+    {
+        if (isProducing())
+            return;
+
+        produceQueue()-&gt;dispatch([this] {
+            CString lower;
+            while (m_lowerQueue.dequeue(lower)) {
+                m_upperQueue.enqueue(toUpper(lower));
+                EXPECT_TRUE(lower == textItem(m_produceCount++));
+                std::this_thread::sleep_for(std::chrono::milliseconds(10));
+            }
+            m_produceCloseSemaphore.signal();
+        });
+    }
+
+    void startConsuming()
+    {
+        if (isConsuming())
+            return;
+
+        consumeQueue()-&gt;dispatch([this] {
+            CString upper;
+            while (m_upperQueue.dequeue(upper)) {
+                EXPECT_TRUE(upper == toUpper(textItem(m_consumeCount++)));
+                std::this_thread::sleep_for(std::chrono::milliseconds(50));
+            }
+            m_consumeCloseSemaphore.signal();
+        });
+    }
+    
+    void start()
+    {
+        startProducing();
+        startConsuming();
+    }
+
+    void stopProducing()
+    {
+        if (!isProducing())
+            return;
+
+        m_lowerQueue.close();
+        m_produceCloseSemaphore.wait(std::numeric_limits&lt;double&gt;::max());
+        m_produceQueue = nullptr;
+    }
+    
+    void stopConsuming()
+    {
+        if (!isConsuming())
+            return;
+
+        m_upperQueue.close();
+        m_consumeCloseSemaphore.wait(std::numeric_limits&lt;double&gt;::max());
+        m_consumeQueue = nullptr;
+    }
+    
+    void stop()
+    {
+        stopProducing();
+        stopConsuming();
+    }
+
+    void enqueueLower(const CString&amp; lower)
+    {
+        m_lowerQueue.enqueue(lower);
+    }
+
+    bool isProducing() { return m_produceQueue; }
+    bool isConsuming() { return m_consumeQueue; }
+
+    size_t produceCount() const { return m_produceCount; }
+    size_t consumeCount() const { return m_consumeCount; }
+
+private:
+    SynchronizedFixedQueue&lt;CString, BufferSize&gt; m_lowerQueue;
+    SynchronizedFixedQueue&lt;CString, BufferSize&gt; m_upperQueue;
+    RefPtr&lt;WorkQueue&gt; m_produceQueue;
+    RefPtr&lt;WorkQueue&gt; m_consumeQueue;
+    BinarySemaphore m_produceCloseSemaphore;
+    BinarySemaphore m_consumeCloseSemaphore;
+    size_t m_produceCount { 0 };
+    size_t m_consumeCount { 0 };
+};
+
+TEST(WTF_SynchronizedFixedQueue, Basic)
+{
+    ToUpperConverter&lt;4U&gt; converter;
+
+    converter.start();
+    EXPECT_TRUE(converter.isProducing() &amp;&amp; converter.isConsuming());
+
+    converter.stop();
+    EXPECT_FALSE(converter.isProducing() || converter.isConsuming());
+
+    EXPECT_EQ(converter.produceCount(), 0U);
+    EXPECT_EQ(converter.consumeCount(), 0U);
+}
+
+TEST(WTF_SynchronizedFixedQueue, ProduceOnly)
+{
+    ToUpperConverter&lt;4U&gt; converter;
+    
+    converter.startProducing();
+    EXPECT_TRUE(converter.isProducing() &amp;&amp; !converter.isConsuming());
+
+    size_t count = 0;
+    while (char const* item = textItem(count)) {
+        converter.enqueueLower(item);
+        ++count;
+        
+        std::this_thread::sleep_for(std::chrono::milliseconds(1));
+    }
+
+    converter.stop();
+    EXPECT_FALSE(converter.isProducing() || converter.isConsuming());
+}
+
+TEST(WTF_SynchronizedFixedQueue, ConsumeOnly)
+{
+    ToUpperConverter&lt;4U&gt; converter;
+    
+    converter.startConsuming();
+    EXPECT_TRUE(!converter.isProducing() &amp;&amp; converter.isConsuming());
+    
+    converter.stop();
+    EXPECT_FALSE(converter.isProducing() || converter.isConsuming());
+}
+
+TEST(WTF_SynchronizedFixedQueue, Limits)
+{
+    ToUpperConverter&lt;4U&gt; converter;
+
+    converter.start();
+    EXPECT_TRUE(converter.isProducing() &amp;&amp; converter.isConsuming());
+
+    size_t count = 0;
+    while (char const* item = textItem(count)) {
+        converter.enqueueLower(item);
+        ++count;
+
+        std::this_thread::sleep_for(std::chrono::milliseconds(1));
+    }
+
+    std::this_thread::sleep_for(std::chrono::milliseconds(400));
+
+    converter.stop();
+    EXPECT_FALSE(converter.isProducing() || converter.isConsuming());
+    
+    EXPECT_EQ(converter.produceCount(), count);
+    EXPECT_EQ(converter.consumeCount(), count);
+}
+
+}
</ins></span></pre>
</div>
</div>

</body>
</html>