<!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>[204245] 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/204245">204245</a></dd>
<dt>Author</dt> <dd>mitz@apple.com</dd>
<dt>Date</dt> <dd>2016-08-07 13:50:43 -0700 (Sun, 07 Aug 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>[Cocoa] Reply block leaks if the remote object doesn’t call it
https://bugs.webkit.org/show_bug.cgi?id=160642

Reviewed by Sam Weinig.

Source/WebKit2:

* Shared/API/Cocoa/RemoteObjectRegistry.h: Declared new member functions.
* Shared/API/Cocoa/RemoteObjectRegistry.messages.in: Added ReleaseUnusedReplyBlock message.
* Shared/API/Cocoa/RemoteObjectRegistry.mm:
(WebKit::RemoteObjectRegistry::sendUnusedReply): Send the ReleaseUnusedReplyBlock message.
(WebKit::RemoteObjectRegistry::releaseUnusedReplyBlock): Message receiver that call through
  to -_releaseReplyWithID:.

* Shared/API/Cocoa/_WKRemoteObjectRegistry.mm:
(-[_WKRemoteObjectRegistry _invokeMethod:]): Define a ReplyBlockCallChecker object and
  capture an instance of it in the reply block we pass to the exported object. Have that
  block set a flag on the checker when it’s called. If the checker gets destroyed without
  the block having been called, which means that the block got destroyed without being
  called, call sendUnusedReply to let the other side know that the block will not be invoked.
(-[_WKRemoteObjectRegistry _releaseReplyWithID:]): Added. Removed the pending reply from the
  map, which release the block.
* Shared/API/Cocoa/_WKRemoteObjectRegistryInternal.h:

Tools:

* TestWebKitAPI/Tests/WebKit2Cocoa/RemoteObjectRegistry.h: Declared a new method.
* TestWebKitAPI/Tests/WebKit2Cocoa/RemoteObjectRegistry.mm:
(TEST): Added a test case that checks that the reply block is released even when it’s not
  called.
* TestWebKitAPI/Tests/WebKit2Cocoa/RemoteObjectRegistryPlugIn.mm:
(-[RemoteObjectRegistryPlugIn doNotCallCompletionHandler:]): Implement new method by not
  calling the completion handler.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2SharedAPICocoaRemoteObjectRegistryh">trunk/Source/WebKit2/Shared/API/Cocoa/RemoteObjectRegistry.h</a></li>
<li><a href="#trunkSourceWebKit2SharedAPICocoaRemoteObjectRegistrymessagesin">trunk/Source/WebKit2/Shared/API/Cocoa/RemoteObjectRegistry.messages.in</a></li>
<li><a href="#trunkSourceWebKit2SharedAPICocoaRemoteObjectRegistrymm">trunk/Source/WebKit2/Shared/API/Cocoa/RemoteObjectRegistry.mm</a></li>
<li><a href="#trunkSourceWebKit2SharedAPICocoa_WKRemoteObjectRegistrymm">trunk/Source/WebKit2/Shared/API/Cocoa/_WKRemoteObjectRegistry.mm</a></li>
<li><a href="#trunkSourceWebKit2SharedAPICocoa_WKRemoteObjectRegistryInternalh">trunk/Source/WebKit2/Shared/API/Cocoa/_WKRemoteObjectRegistryInternal.h</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsTestWebKitAPITestsWebKit2CocoaRemoteObjectRegistryh">trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/RemoteObjectRegistry.h</a></li>
<li><a href="#trunkToolsTestWebKitAPITestsWebKit2CocoaRemoteObjectRegistrymm">trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/RemoteObjectRegistry.mm</a></li>
<li><a href="#trunkToolsTestWebKitAPITestsWebKit2CocoaRemoteObjectRegistryPlugInmm">trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/RemoteObjectRegistryPlugIn.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (204244 => 204245)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2016-08-07 19:40:59 UTC (rev 204244)
+++ trunk/Source/WebKit2/ChangeLog        2016-08-07 20:50:43 UTC (rev 204245)
</span><span class="lines">@@ -1,3 +1,27 @@
</span><ins>+2016-08-07  Dan Bernstein  &lt;mitz@apple.com&gt;
+
+        [Cocoa] Reply block leaks if the remote object doesn’t call it
+        https://bugs.webkit.org/show_bug.cgi?id=160642
+
+        Reviewed by Sam Weinig.
+
+        * Shared/API/Cocoa/RemoteObjectRegistry.h: Declared new member functions.
+        * Shared/API/Cocoa/RemoteObjectRegistry.messages.in: Added ReleaseUnusedReplyBlock message.
+        * Shared/API/Cocoa/RemoteObjectRegistry.mm:
+        (WebKit::RemoteObjectRegistry::sendUnusedReply): Send the ReleaseUnusedReplyBlock message.
+        (WebKit::RemoteObjectRegistry::releaseUnusedReplyBlock): Message receiver that call through
+          to -_releaseReplyWithID:.
+
+        * Shared/API/Cocoa/_WKRemoteObjectRegistry.mm:
+        (-[_WKRemoteObjectRegistry _invokeMethod:]): Define a ReplyBlockCallChecker object and
+          capture an instance of it in the reply block we pass to the exported object. Have that
+          block set a flag on the checker when it’s called. If the checker gets destroyed without
+          the block having been called, which means that the block got destroyed without being
+          called, call sendUnusedReply to let the other side know that the block will not be invoked.
+        (-[_WKRemoteObjectRegistry _releaseReplyWithID:]): Added. Removed the pending reply from the
+          map, which release the block.
+        * Shared/API/Cocoa/_WKRemoteObjectRegistryInternal.h:
+
</ins><span class="cx"> 2016-08-07  Chris Dumez  &lt;cdumez@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Write API test to cover crash fix in r204135
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedAPICocoaRemoteObjectRegistryh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/API/Cocoa/RemoteObjectRegistry.h (204244 => 204245)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/API/Cocoa/RemoteObjectRegistry.h        2016-08-07 19:40:59 UTC (rev 204244)
+++ trunk/Source/WebKit2/Shared/API/Cocoa/RemoteObjectRegistry.h        2016-08-07 20:50:43 UTC (rev 204245)
</span><span class="lines">@@ -46,6 +46,7 @@
</span><span class="cx"> 
</span><span class="cx">     void sendInvocation(const RemoteObjectInvocation&amp;);
</span><span class="cx">     void sendReplyBlock(uint64_t replyID, const UserData&amp; blockInvocation);
</span><ins>+    void sendUnusedReply(uint64_t replyID);
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     // IPC::MessageReceiver
</span><span class="lines">@@ -54,6 +55,7 @@
</span><span class="cx">     // Message handlers
</span><span class="cx">     void invokeMethod(const RemoteObjectInvocation&amp;);
</span><span class="cx">     void callReplyBlock(uint64_t replyID, const UserData&amp; blockInvocation);
</span><ins>+    void releaseUnusedReplyBlock(uint64_t replyID);
</ins><span class="cx"> 
</span><span class="cx">     _WKRemoteObjectRegistry *m_remoteObjectRegistry;
</span><span class="cx">     IPC::MessageSender&amp; m_messageSender;
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedAPICocoaRemoteObjectRegistrymessagesin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/API/Cocoa/RemoteObjectRegistry.messages.in (204244 => 204245)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/API/Cocoa/RemoteObjectRegistry.messages.in        2016-08-07 19:40:59 UTC (rev 204244)
+++ trunk/Source/WebKit2/Shared/API/Cocoa/RemoteObjectRegistry.messages.in        2016-08-07 20:50:43 UTC (rev 204245)
</span><span class="lines">@@ -23,4 +23,5 @@
</span><span class="cx"> messages -&gt; RemoteObjectRegistry {
</span><span class="cx">     InvokeMethod(WebKit::RemoteObjectInvocation invocation)
</span><span class="cx">     CallReplyBlock(uint64_t replyID, WebKit::UserData blockInvocation);
</span><ins>+    ReleaseUnusedReplyBlock(uint64_t replyID);
</ins><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedAPICocoaRemoteObjectRegistrymm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/API/Cocoa/RemoteObjectRegistry.mm (204244 => 204245)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/API/Cocoa/RemoteObjectRegistry.mm        2016-08-07 19:40:59 UTC (rev 204244)
+++ trunk/Source/WebKit2/Shared/API/Cocoa/RemoteObjectRegistry.mm        2016-08-07 20:50:43 UTC (rev 204245)
</span><span class="lines">@@ -54,6 +54,11 @@
</span><span class="cx">     m_messageSender.send(Messages::RemoteObjectRegistry::CallReplyBlock(replyID, blockInvocation));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void RemoteObjectRegistry::sendUnusedReply(uint64_t replyID)
+{
+    m_messageSender.send(Messages::RemoteObjectRegistry::ReleaseUnusedReplyBlock(replyID));
+}
+
</ins><span class="cx"> void RemoteObjectRegistry::invokeMethod(const RemoteObjectInvocation&amp; invocation)
</span><span class="cx"> {
</span><span class="cx"> #if WK_API_ENABLED
</span><span class="lines">@@ -68,4 +73,10 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void RemoteObjectRegistry::releaseUnusedReplyBlock(uint64_t replyID)
+{
+#if WK_API_ENABLED
+    [m_remoteObjectRegistry _releaseReplyWithID:replyID];
+#endif
+}
</ins><span class="cx"> } // namespace WebKit
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedAPICocoa_WKRemoteObjectRegistrymm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/API/Cocoa/_WKRemoteObjectRegistry.mm (204244 => 204245)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/API/Cocoa/_WKRemoteObjectRegistry.mm        2016-08-07 19:40:59 UTC (rev 204244)
+++ trunk/Source/WebKit2/Shared/API/Cocoa/_WKRemoteObjectRegistry.mm        2016-08-07 20:50:43 UTC (rev 204245)
</span><span class="lines">@@ -216,11 +216,38 @@
</span><span class="cx"> 
</span><span class="cx">             RetainPtr&lt;_WKRemoteObjectRegistry&gt; remoteObjectRegistry = self;
</span><span class="cx">             uint64_t replyID = replyInfo-&gt;replyID;
</span><del>-            id replyBlock = __NSMakeSpecialForwardingCaptureBlock(wireBlockSignature._typeString.UTF8String, [interface, remoteObjectRegistry, replyID](NSInvocation *invocation) {
</del><ins>+
+            class ReplyBlockCallChecker : public WTF::ThreadSafeRefCounted&lt;ReplyBlockCallChecker&gt; {
+            public:
+                static Ref&lt;ReplyBlockCallChecker&gt; create(_WKRemoteObjectRegistry *registry, uint64_t replyID) { return adoptRef(*new ReplyBlockCallChecker(registry, replyID)); }
+
+                ~ReplyBlockCallChecker()
+                {
+                    if (!m_didCallReplyBlock)
+                        m_remoteObjectRegistry-&gt;_remoteObjectRegistry-&gt;sendUnusedReply(m_replyID);
+                }
+
+                void didCallReplyBlock() { m_didCallReplyBlock = true; }
+
+            private:
+                ReplyBlockCallChecker(_WKRemoteObjectRegistry *registry, uint64_t replyID)
+                    : m_remoteObjectRegistry(registry)
+                    , m_replyID(replyID)
+                {
+                }
+
+                RetainPtr&lt;_WKRemoteObjectRegistry&gt; m_remoteObjectRegistry;
+                uint64_t m_replyID = 0;
+                bool m_didCallReplyBlock = false;
+            };
+
+            RefPtr&lt;ReplyBlockCallChecker&gt; checker = ReplyBlockCallChecker::create(self, replyID);
+            id replyBlock = __NSMakeSpecialForwardingCaptureBlock(wireBlockSignature._typeString.UTF8String, [interface, remoteObjectRegistry, replyID, checker](NSInvocation *invocation) {
</ins><span class="cx">                 auto encoder = adoptNS([[WKRemoteObjectEncoder alloc] init]);
</span><span class="cx">                 [encoder encodeObject:invocation forKey:invocationKey];
</span><span class="cx"> 
</span><span class="cx">                 remoteObjectRegistry-&gt;_remoteObjectRegistry-&gt;sendReplyBlock(replyID, UserData([encoder rootObjectDictionary]));
</span><ins>+                checker-&gt;didCallReplyBlock();
</ins><span class="cx">             });
</span><span class="cx"> 
</span><span class="cx">             [invocation setArgument:&amp;replyBlock atIndex:i];
</span><span class="lines">@@ -270,6 +297,11 @@
</span><span class="cx">     [replyInvocation invoke];
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+- (void)_releaseReplyWithID:(uint64_t)replyID
+{
+    _pendingReplies.remove(replyID);
+}
+
</ins><span class="cx"> @end
</span><span class="cx"> 
</span><span class="cx"> #endif // WK_API_ENABLED
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedAPICocoa_WKRemoteObjectRegistryInternalh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/API/Cocoa/_WKRemoteObjectRegistryInternal.h (204244 => 204245)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/API/Cocoa/_WKRemoteObjectRegistryInternal.h        2016-08-07 19:40:59 UTC (rev 204244)
+++ trunk/Source/WebKit2/Shared/API/Cocoa/_WKRemoteObjectRegistryInternal.h        2016-08-07 20:50:43 UTC (rev 204245)
</span><span class="lines">@@ -48,6 +48,7 @@
</span><span class="cx"> - (void)_invokeMethod:(const WebKit::RemoteObjectInvocation&amp;)invocation;
</span><span class="cx"> 
</span><span class="cx"> - (void)_callReplyWithID:(uint64_t)replyID blockInvocation:(const WebKit::UserData&amp;)blockInvocation;
</span><ins>+- (void)_releaseReplyWithID:(uint64_t)replyID;
</ins><span class="cx"> 
</span><span class="cx"> @end
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (204244 => 204245)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog        2016-08-07 19:40:59 UTC (rev 204244)
+++ trunk/Tools/ChangeLog        2016-08-07 20:50:43 UTC (rev 204245)
</span><span class="lines">@@ -1,3 +1,18 @@
</span><ins>+2016-08-07  Dan Bernstein  &lt;mitz@apple.com&gt;
+
+        [Cocoa] Reply block leaks if the remote object doesn’t call it
+        https://bugs.webkit.org/show_bug.cgi?id=160642
+
+        Reviewed by Sam Weinig.
+
+        * TestWebKitAPI/Tests/WebKit2Cocoa/RemoteObjectRegistry.h: Declared a new method.
+        * TestWebKitAPI/Tests/WebKit2Cocoa/RemoteObjectRegistry.mm:
+        (TEST): Added a test case that checks that the reply block is released even when it’s not
+          called.
+        * TestWebKitAPI/Tests/WebKit2Cocoa/RemoteObjectRegistryPlugIn.mm:
+        (-[RemoteObjectRegistryPlugIn doNotCallCompletionHandler:]): Implement new method by not
+          calling the completion handler.
+
</ins><span class="cx"> 2016-08-07  Chris Dumez  &lt;cdumez@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Write API test to cover crash fix in r204135
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPITestsWebKit2CocoaRemoteObjectRegistryh"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/RemoteObjectRegistry.h (204244 => 204245)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/RemoteObjectRegistry.h        2016-08-07 19:40:59 UTC (rev 204244)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/RemoteObjectRegistry.h        2016-08-07 20:50:43 UTC (rev 204245)
</span><span class="lines">@@ -35,6 +35,7 @@
</span><span class="cx"> - (void)sayHello:(NSString *)hello completionHandler:(void (^)(NSString *))completionHandler;
</span><span class="cx"> - (void)selectionAndClickInformationForClickAtPoint:(NSValue *)pointValue completionHandler:(void (^)(NSDictionary *))completionHandler;
</span><span class="cx"> - (void)takeRange:(NSRange)range completionHandler:(void (^)(NSUInteger location, NSUInteger length))completionHandler;
</span><ins>+- (void)doNotCallCompletionHandler:(void (^)())completionHandler;
</ins><span class="cx"> 
</span><span class="cx"> @end
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPITestsWebKit2CocoaRemoteObjectRegistrymm"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/RemoteObjectRegistry.mm (204244 => 204245)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/RemoteObjectRegistry.mm        2016-08-07 19:40:59 UTC (rev 204244)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/RemoteObjectRegistry.mm        2016-08-07 20:50:43 UTC (rev 204245)
</span><span class="lines">@@ -35,6 +35,7 @@
</span><span class="cx"> #import &lt;WebKit/WKWebViewPrivate.h&gt;
</span><span class="cx"> #import &lt;WebKit/_WKRemoteObjectInterface.h&gt;
</span><span class="cx"> #import &lt;WebKit/_WKRemoteObjectRegistry.h&gt;
</span><ins>+#import &lt;wtf/RefCounted.h&gt;
</ins><span class="cx"> #import &lt;wtf/RetainPtr.h&gt;
</span><span class="cx"> 
</span><span class="cx"> static bool isDone;
</span><span class="lines">@@ -82,6 +83,21 @@
</span><span class="cx">             isDone = true;
</span><span class="cx">         }];
</span><span class="cx">         TestWebKitAPI::Util::run(&amp;isDone);
</span><ins>+
+        isDone = false;
+
+        class DoneWhenDestroyed : public RefCounted&lt;DoneWhenDestroyed&gt; {
+        public:
+            ~DoneWhenDestroyed() { isDone = true; }
+        };
+
+        {
+            RefPtr&lt;DoneWhenDestroyed&gt; doneWhenDestroyed = adoptRef(*new DoneWhenDestroyed);
+            [object doNotCallCompletionHandler:[doneWhenDestroyed]() {
+            }];
+        }
+
+        TestWebKitAPI::Util::run(&amp;isDone);
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPITestsWebKit2CocoaRemoteObjectRegistryPlugInmm"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/RemoteObjectRegistryPlugIn.mm (204244 => 204245)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/RemoteObjectRegistryPlugIn.mm        2016-08-07 19:40:59 UTC (rev 204244)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/RemoteObjectRegistryPlugIn.mm        2016-08-07 20:50:43 UTC (rev 204245)
</span><span class="lines">@@ -81,6 +81,10 @@
</span><span class="cx">     completionHandler(range.location, range.length);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+- (void)doNotCallCompletionHandler:(void (^)())completionHandler
+{
+}
+
</ins><span class="cx"> @end
</span><span class="cx"> 
</span><span class="cx"> #endif // WK_API_ENABLED
</span></span></pre>
</div>
</div>

</body>
</html>