Title: [258117] trunk/Source/WebKit
Revision
258117
Author
beid...@apple.com
Date
2020-03-08 16:04:51 -0700 (Sun, 08 Mar 2020)

Log Message

Better stream loader management with incremental PDF loading.
https://bugs.webkit.org/show_bug.cgi?id=208790

Reviewed by Tim Horton.

When a stream loader was completing normally, we were leaking it forever.
This adds much better management of outstanding stream loaders
(and logging to help verify the count is as expected)

* WebProcess/Plugins/PDF/PDFPlugin.h:
* WebProcess/Plugins/PDF/PDFPlugin.mm:
(WebKit::PDFPlugin::getResourceBytesAtPosition):
(WebKit::PDFPlugin::ByteRangeRequest::completeWithBytes):
(WebKit::PDFPlugin::ByteRangeRequest::completeWithAccumulatedData):
(WebKit::PDFPlugin::ByteRangeRequest::maybeComplete):
(WebKit::PDFPlugin::ByteRangeRequest::completeUnconditionally):
(WebKit::PDFPlugin::didReceiveResponse):
(WebKit::PDFPlugin::didFinishLoading):
(WebKit::PDFPlugin::forgetLoader):
(WebKit::PDFPlugin::cancelAndForgetLoader):

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (258116 => 258117)


--- trunk/Source/WebKit/ChangeLog	2020-03-08 22:33:30 UTC (rev 258116)
+++ trunk/Source/WebKit/ChangeLog	2020-03-08 23:04:51 UTC (rev 258117)
@@ -1,3 +1,26 @@
+2020-03-08  Brady Eidson  <beid...@apple.com>
+
+        Better stream loader management with incremental PDF loading.
+        https://bugs.webkit.org/show_bug.cgi?id=208790
+
+        Reviewed by Tim Horton.
+
+        When a stream loader was completing normally, we were leaking it forever.
+        This adds much better management of outstanding stream loaders
+        (and logging to help verify the count is as expected)
+
+        * WebProcess/Plugins/PDF/PDFPlugin.h:
+        * WebProcess/Plugins/PDF/PDFPlugin.mm:
+        (WebKit::PDFPlugin::getResourceBytesAtPosition):
+        (WebKit::PDFPlugin::ByteRangeRequest::completeWithBytes):
+        (WebKit::PDFPlugin::ByteRangeRequest::completeWithAccumulatedData):
+        (WebKit::PDFPlugin::ByteRangeRequest::maybeComplete):
+        (WebKit::PDFPlugin::ByteRangeRequest::completeUnconditionally):
+        (WebKit::PDFPlugin::didReceiveResponse):
+        (WebKit::PDFPlugin::didFinishLoading):
+        (WebKit::PDFPlugin::forgetLoader):
+        (WebKit::PDFPlugin::cancelAndForgetLoader):
+
 2020-03-08  Konstantin Tokarev  <annu...@yandex.ru>
 
         [CMake] Some fixes for building Mac port

Modified: trunk/Source/WebKit/WebProcess/Plugins/PDF/PDFPlugin.h (258116 => 258117)


--- trunk/Source/WebKit/WebProcess/Plugins/PDF/PDFPlugin.h	2020-03-08 22:33:30 UTC (rev 258116)
+++ trunk/Source/WebKit/WebProcess/Plugins/PDF/PDFPlugin.h	2020-03-08 23:04:51 UTC (rev 258117)
@@ -345,8 +345,8 @@
         void clearStreamLoader();
         void addData(const uint8_t* data, size_t count) { m_accumulatedData.append(data, count); }
 
-        void completeWithBytes(const uint8_t*, size_t);
-        void completeWithAccumulatedData();
+        void completeWithBytes(const uint8_t*, size_t, PDFPlugin&);
+        void completeWithAccumulatedData(PDFPlugin&);
 
         bool maybeComplete(PDFPlugin&);
         void completeUnconditionally(PDFPlugin&);
@@ -361,6 +361,7 @@
     void unconditionalCompleteOutstandingRangeRequests();
 
     ByteRangeRequest* byteRangeRequestForLoader(WebCore::NetscapePlugInStreamLoader&);
+    void forgetLoader(WebCore::NetscapePlugInStreamLoader&);
     void cancelAndForgetLoader(WebCore::NetscapePlugInStreamLoader&);
 
     RetainPtr<PDFDocument> m_backgroundThreadDocument;

Modified: trunk/Source/WebKit/WebProcess/Plugins/PDF/PDFPlugin.mm (258116 => 258117)


--- trunk/Source/WebKit/WebProcess/Plugins/PDF/PDFPlugin.mm	2020-03-08 22:33:30 UTC (rev 258116)
+++ trunk/Source/WebKit/WebProcess/Plugins/PDF/PDFPlugin.mm	2020-03-08 23:04:51 UTC (rev 258117)
@@ -773,11 +773,14 @@
 
     WebProcess::singleton().webLoaderStrategy().schedulePluginStreamLoad(*coreFrame, *this, WTFMove(resourceRequest), [this, protectedThis = makeRef(*this), identifier] (RefPtr<WebCore::NetscapePlugInStreamLoader>&& loader) {
         auto iterator = m_outstandingByteRangeRequests.find(identifier);
-        if (iterator == m_outstandingByteRangeRequests.end())
+        if (iterator == m_outstandingByteRangeRequests.end()) {
+            loader->cancel(loader->cancelledError());
             return;
+        }
 
         iterator->value.setStreamLoader(loader.get());
         m_streamLoaderMap.set(WTFMove(loader), identifier);
+        LOG(PDF, "There are now %u stream loaders in flight", m_streamLoaderMap.size());
     });
 }
 
@@ -809,22 +812,28 @@
     m_accumulatedData.clear();
 }
 
-void PDFPlugin::ByteRangeRequest::completeWithBytes(const uint8_t* data, size_t count)
+void PDFPlugin::ByteRangeRequest::completeWithBytes(const uint8_t* data, size_t count, PDFPlugin& plugin)
 {
     LOG(PDF, "Completing range request %llu (%lu bytes at %llu) with %lu bytes from the main PDF buffer", identifier(), m_count, m_position, count);
     m_completionHandler(data, count);
+
+    if (m_streamLoader)
+        plugin.forgetLoader(*m_streamLoader);
 }
 
-void PDFPlugin::ByteRangeRequest::completeWithAccumulatedData()
+void PDFPlugin::ByteRangeRequest::completeWithAccumulatedData(PDFPlugin& plugin)
 {
     LOG(PDF, "Completing range request %llu (%lu bytes at %llu) with %lu bytes from the network", identifier(), m_count, m_position, m_accumulatedData.size());
     m_completionHandler(m_accumulatedData.data(), m_accumulatedData.size());
+    
+    if (m_streamLoader)
+        plugin.forgetLoader(*m_streamLoader);
 }
 
 bool PDFPlugin::ByteRangeRequest::maybeComplete(PDFPlugin& plugin)
 {
     if (plugin.m_streamedBytes >= m_position + m_count) {
-        completeWithBytes(CFDataGetBytePtr(plugin.m_data.get()) + m_position, m_count);
+        completeWithBytes(CFDataGetBytePtr(plugin.m_data.get()) + m_position, m_count, plugin);
         return true;
     }
     return false;
@@ -833,7 +842,7 @@
 void PDFPlugin::ByteRangeRequest::completeUnconditionally(PDFPlugin& plugin)
 {
     if (m_position >= plugin.m_streamedBytes) {
-        completeWithBytes(nullptr, 0);
+        completeWithBytes(nullptr, 0, plugin);
         return;
     }
 
@@ -840,7 +849,7 @@
     ASSERT(plugin.m_data);
 
     auto count = m_position + m_count > plugin.m_streamedBytes ? plugin.m_streamedBytes - m_position : m_count;
-    completeWithBytes(CFDataGetBytePtr(plugin.m_data.get()) + m_position, count);
+    completeWithBytes(CFDataGetBytePtr(plugin.m_data.get()) + m_position, count, plugin);
 }
 
 void PDFPlugin::willSendRequest(NetscapePlugInStreamLoader* loader, ResourceRequest&&, const ResourceResponse&, CompletionHandler<void(ResourceRequest&&)>&&)
@@ -852,8 +861,10 @@
 void PDFPlugin::didReceiveResponse(NetscapePlugInStreamLoader* loader, const ResourceResponse& response)
 {
     auto* request = byteRangeRequestForLoader(*loader);
-    if (!request)
+    if (!request) {
         cancelAndForgetLoader(*loader);
+        return;
+    }
 
     ASSERT(request->streamLoader() == loader);
 
@@ -869,7 +880,7 @@
     // The server might support range requests and explicitly told us this range was not satisfiable.
     // In this case, we can reject the ByteRangeRequest right away.
     if (response.httpStatusCode() == 416 && request) {
-        request->completeWithAccumulatedData();
+        request->completeWithAccumulatedData(*this);
         m_outstandingByteRangeRequests.remove(request->identifier());
     }
 }
@@ -900,7 +911,7 @@
     if (!request)
         return;
 
-    request->completeWithAccumulatedData();
+    request->completeWithAccumulatedData(*this);
     m_outstandingByteRangeRequests.remove(request->identifier());
 }
 
@@ -917,8 +928,14 @@
     return &(request->value);
 }
 
-void PDFPlugin::cancelAndForgetLoader(NetscapePlugInStreamLoader& loader)
+void PDFPlugin::forgetLoader(NetscapePlugInStreamLoader& loader)
 {
+    uint64_t identifier = m_streamLoaderMap.get(&loader);
+    if (!identifier) {
+        ASSERT(!m_streamLoaderMap.contains(&loader));
+        return;
+    }
+
     if (auto* request = byteRangeRequestForLoader(loader)) {
         if (request->streamLoader()) {
             ASSERT(request->streamLoader() == &loader);
@@ -926,9 +943,17 @@
         }
     }
 
-    loader.cancel(loader.cancelledError());
     m_streamLoaderMap.remove(&loader);
+
+    LOG(PDF, "Forgot stream loader for range request %llu.\nThere are now %u stream loaders remaining.", identifier, m_streamLoaderMap.size());
 }
+
+void PDFPlugin::cancelAndForgetLoader(NetscapePlugInStreamLoader& loader)
+{
+    auto protectedLoader = makeRef(loader);
+    forgetLoader(loader);
+    loader.cancel(loader.cancelledError());
+}
 #endif // HAVE(INCREMENTAL_PDF_APIS)
 
 PluginInfo PDFPlugin::pluginInfo()
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to