Changeset 280547 in webkit
- Timestamp:
- Aug 2, 2021, 11:46:51 AM (5 years ago)
- Location:
- trunk
- Files:
-
- 24 edited
-
LayoutTests/ChangeLog (modified) (1 diff)
-
LayoutTests/platform/ios-wk2/TestExpectations (modified) (1 diff)
-
LayoutTests/platform/mac/TestExpectations (modified) (1 diff)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/Modules/indexeddb/IDBValue.cpp (modified) (1 diff)
-
Source/WebCore/bindings/js/SerializedScriptValue.cpp (modified) (20 diffs)
-
Source/WebCore/bindings/js/SerializedScriptValue.h (modified) (4 diffs)
-
Source/WebCore/dom/BroadcastChannel.cpp (modified) (4 diffs)
-
Source/WebCore/dom/BroadcastChannel.h (modified) (1 diff)
-
Source/WebCore/dom/BroadcastChannelRegistry.h (modified) (2 diffs)
-
Source/WebCore/fileapi/Blob.cpp (modified) (11 diffs)
-
Source/WebCore/fileapi/Blob.h (modified) (4 diffs)
-
Source/WebCore/loader/EmptyClients.cpp (modified) (1 diff)
-
Source/WebKit/ChangeLog (modified) (1 diff)
-
Source/WebKit/NetworkProcess/NetworkBroadcastChannelRegistry.cpp (modified) (3 diffs)
-
Source/WebKit/NetworkProcess/NetworkBroadcastChannelRegistry.h (modified) (1 diff)
-
Source/WebKit/NetworkProcess/NetworkBroadcastChannelRegistry.messages.in (modified) (1 diff)
-
Source/WebKit/Platform/IPC/HandleMessage.h (modified) (1 diff)
-
Source/WebKit/WebProcess/WebCoreSupport/WebBroadcastChannelRegistry.cpp (modified) (1 diff)
-
Source/WebKit/WebProcess/WebCoreSupport/WebBroadcastChannelRegistry.h (modified) (2 diffs)
-
Source/WebKit/WebProcess/WebCoreSupport/WebBroadcastChannelRegistry.messages.in (modified) (1 diff)
-
Source/WebKitLegacy/ChangeLog (modified) (1 diff)
-
Source/WebKitLegacy/WebCoreSupport/WebBroadcastChannelRegistry.cpp (modified) (3 diffs)
-
Source/WebKitLegacy/WebCoreSupport/WebBroadcastChannelRegistry.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r280543 r280547 1 2021-08-02 Chris Dumez <cdumez@apple.com> 2 3 imported/w3c/web-platform-tests/webmessaging/broadcastchannel/blobs.html is a flaky failure since implementing BlobChannel 4 https://bugs.webkit.org/show_bug.cgi?id=228168 5 <rdar://problem/80922502> 6 7 Reviewed by Alex Christensen. 8 9 Unskip test that is no longer flaky. 10 11 * platform/ios-wk2/TestExpectations: 12 * platform/mac/TestExpectations: 13 1 14 2021-08-02 Wenson Hsieh <wenson_hsieh@apple.com> 2 15 -
trunk/LayoutTests/platform/ios-wk2/TestExpectations
r280532 r280547 1995 1995 webkit.org/b/228114 imported/w3c/web-platform-tests/fetch/content-type/script.window.html [ Pass Failure ] 1996 1996 1997 webkit.org/b/228168 imported/w3c/web-platform-tests/webmessaging/broadcastchannel/blobs.html [ Pass Failure ]1998 1999 1997 webkit.org/b/227998 imported/w3c/web-platform-tests/html/semantics/embedded-content/the-embed-element/embed-network-error.sub.html [ Pass Failure ] 2000 1998 -
trunk/LayoutTests/platform/mac/TestExpectations
r280504 r280547 2297 2297 webkit.org/b/214574 svg/animations/smil-leak-list-property-instances.svg [ Pass Failure ] 2298 2298 2299 webkit.org/b/228168 imported/w3c/web-platform-tests/webmessaging/broadcastchannel/blobs.html [ Pass Failure ]2300 2301 2299 webkit.org/b/222385 imported/w3c/web-platform-tests/xhr/event-upload-progress-crossorigin.any.worker.html [ Pass Failure ] 2302 2300 -
trunk/Source/WebCore/ChangeLog
r280543 r280547 1 2021-08-02 Chris Dumez <cdumez@apple.com> 2 3 imported/w3c/web-platform-tests/webmessaging/broadcastchannel/blobs.html is a flaky failure since implementing BlobChannel 4 https://bugs.webkit.org/show_bug.cgi?id=228168 5 <rdar://problem/80922502> 6 7 Reviewed by Alex Christensen. 8 9 The test was flaky because it is trying to send a Blob via BroadcastChannel.postMessage() 10 without keeping the blob alive. When GC triggers, the Blob would go away and trying to 11 decode the Blob upon receiving would fail. 12 13 To address the issue, I introduced a Blob::Handle class that wraps the Blob's internal URL 14 and keeps the Blob data alive as long as as someone is holding such handle. Previously, 15 the Blob destructor would unregister the internal URL and the Blob data would go away. 16 17 I then updated SerializedScriptValue to hold on to Blob::Handle objects instead of Blob 18 URLs. This guarantees that when using postMessage() to send a message to a worker, the 19 Blob data will stay alive until we dispatch the message event on the worker side and try 20 and deserialized the SerializedScriptValue. 21 22 For BroadcastChannel.postMessage() though, we end up going via the network process and 23 the SerializedScriptValue ends up getting serialized/deserialized over IPC. I added a 24 CompletionHandler to BroadcastChannelRegistry::postMessage() which only gets called 25 once the message event has successfully been dispatched. I use this completion handler 26 to make sure the SerializedScriptValue's Blob URLs stay valid until the the message has 27 been dispatched by holding on to the Blob::Handles. 28 29 No new tests, unskipped existing test. 30 31 * Modules/indexeddb/IDBValue.cpp: 32 (WebCore::IDBValue::IDBValue): 33 * bindings/js/SerializedScriptValue.cpp: 34 (WebCore::CloneSerializer::serialize): 35 (WebCore::CloneSerializer::CloneSerializer): 36 (WebCore::CloneSerializer::dumpIfTerminal): 37 (WebCore::CloneSerializer::write): 38 (WebCore::SerializedScriptValue::SerializedScriptValue): 39 (WebCore::SerializedScriptValue::computeMemoryCost const): 40 (WebCore::SerializedScriptValue::create): 41 (WebCore::SerializedScriptValue::blobURLs const): 42 (WebCore::SerializedScriptValue::writeBlobsToDiskForIndexedDB): 43 * bindings/js/SerializedScriptValue.h: 44 (WebCore::SerializedScriptValue::hasBlobURLs const): 45 (WebCore::SerializedScriptValue::blobHandles const): 46 (WebCore::SerializedScriptValue::SerializedScriptValue): 47 * dom/BroadcastChannel.cpp: 48 (WebCore::BroadcastChannel::postMessage): 49 (WebCore::BroadcastChannel::dispatchMessageTo): 50 * dom/BroadcastChannel.h: 51 * dom/BroadcastChannelRegistry.h: 52 * fileapi/Blob.cpp: 53 (WebCore::BlobInternalURL::create): 54 (WebCore::BlobInternalURL::~BlobInternalURL): 55 (WebCore::BlobInternalURL::url const): 56 (WebCore::BlobInternalURL::BlobInternalURL): 57 (WebCore::Blob::Blob): 58 (WebCore::Blob::~Blob): 59 (WebCore::Blob::url const): 60 (WebCore::Blob::slice const): 61 (WebCore::Blob::size const): 62 (WebCore::Blob::handle const): 63 (WebCore::Blob::Handle::Handle): 64 (WebCore::Blob::Handle::url const): 65 * fileapi/Blob.h: 66 * loader/EmptyClients.cpp: 67 1 68 2021-08-02 Wenson Hsieh <wenson_hsieh@apple.com> 2 69 -
trunk/Source/WebCore/Modules/indexeddb/IDBValue.cpp
r275151 r280547 38 38 IDBValue::IDBValue(const SerializedScriptValue& scriptValue) 39 39 : m_data(ThreadSafeDataBuffer::copyVector(scriptValue.data())) 40 , m_blobURLs(scriptValue.blobURLs IsolatedCopy())40 , m_blobURLs(scriptValue.blobURLs()) 41 41 { 42 42 } -
trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp
r280476 r280547 601 601 WasmMemoryHandleArray& wasmMemoryHandles, 602 602 #endif 603 Vector< String>& blobURLs, Vector<uint8_t>& out, SerializationContext context, ArrayBufferContentsArray& sharedBuffers)603 Vector<Blob::Handle>& blobHandles, Vector<uint8_t>& out, SerializationContext context, ArrayBufferContentsArray& sharedBuffers) 604 604 { 605 605 CloneSerializer serializer(lexicalGlobalObject, messagePorts, arrayBuffers, imageBitmaps, … … 614 614 wasmMemoryHandles, 615 615 #endif 616 blob URLs, out, context, sharedBuffers);616 blobHandles, out, context, sharedBuffers); 617 617 return serializer.serialize(value); 618 618 } … … 648 648 WasmMemoryHandleArray& wasmMemoryHandles, 649 649 #endif 650 Vector< String>& blobURLs, Vector<uint8_t>& out, SerializationContext context, ArrayBufferContentsArray& sharedBuffers)650 Vector<Blob::Handle>& blobHandles, Vector<uint8_t>& out, SerializationContext context, ArrayBufferContentsArray& sharedBuffers) 651 651 : CloneBase(lexicalGlobalObject) 652 652 , m_buffer(out) 653 , m_blob URLs(blobURLs)653 , m_blobHandles(blobHandles) 654 654 , m_emptyIdentifier(Identifier::fromString(lexicalGlobalObject->vm(), emptyString())) 655 655 , m_context(context) … … 1225 1225 if (auto* blob = JSBlob::toWrapped(vm, obj)) { 1226 1226 write(BlobTag); 1227 m_blob URLs.append(blob->url().string());1227 m_blobHandles.append(blob->handle()); 1228 1228 write(blob->url().string()); 1229 1229 write(blob->type()); … … 1298 1298 write(CryptoKeyTag); 1299 1299 Vector<uint8_t> serializedKey; 1300 Vector< String> dummyBlobURLs;1300 Vector<Blob::Handle> dummyBlobHandles; 1301 1301 Vector<RefPtr<MessagePort>> dummyMessagePorts; 1302 1302 Vector<RefPtr<JSC::ArrayBuffer>> dummyArrayBuffers; … … 1317 1317 dummyMemoryHandles, 1318 1318 #endif 1319 dummyBlob URLs, serializedKey, SerializationContext::Default, dummySharedBuffers);1319 dummyBlobHandles, serializedKey, SerializationContext::Default, dummySharedBuffers); 1320 1320 rawKeySerializer.write(key); 1321 1321 Vector<uint8_t> wrappedKey; … … 1551 1551 void write(const File& file) 1552 1552 { 1553 m_blob URLs.append(file.url().string());1553 m_blobHandles.append(file.handle()); 1554 1554 write(file.path()); 1555 1555 write(file.url().string()); … … 1761 1761 1762 1762 Vector<uint8_t>& m_buffer; 1763 Vector< String>& m_blobURLs;1763 Vector<Blob::Handle>& m_blobHandles; 1764 1764 ObjectPool m_objectPool; 1765 1765 ObjectPool m_transferredMessagePorts; … … 3916 3916 } 3917 3917 3918 SerializedScriptValue::SerializedScriptValue(Vector<uint8_t>&& buffer, const Vector< String>& blobURLs, std::unique_ptr<ArrayBufferContentsArray> arrayBufferContentsArray, std::unique_ptr<ArrayBufferContentsArray> sharedBufferContentsArray, Vector<std::optional<ImageBitmapBacking>>&& backingStores3918 SerializedScriptValue::SerializedScriptValue(Vector<uint8_t>&& buffer, const Vector<Blob::Handle>& blobHandles, std::unique_ptr<ArrayBufferContentsArray> arrayBufferContentsArray, std::unique_ptr<ArrayBufferContentsArray> sharedBufferContentsArray, Vector<std::optional<ImageBitmapBacking>>&& backingStores 3919 3919 #if ENABLE(OFFSCREEN_CANVAS_IN_WORKERS) 3920 3920 , Vector<std::unique_ptr<DetachedOffscreenCanvas>>&& detachedOffscreenCanvases … … 3942 3942 , m_wasmMemoryHandlesArray(WTFMove(wasmMemoryHandlesArray)) 3943 3943 #endif 3944 , m_blobHandles(blobHandles) 3944 3945 { 3945 // Since this SerializedScriptValue is meant to be passed between threads, its String data members3946 // need to be isolatedCopies so we don't run into thread safety issues for the StringImpls.3947 m_blobURLs.reserveInitialCapacity(blobURLs.size());3948 for (auto& url : blobURLs)3949 m_blobURLs.uncheckedAppend(url.isolatedCopy());3950 3946 m_memoryCost = computeMemoryCost(); 3951 3947 } … … 3991 3987 #endif 3992 3988 3993 for (auto& urls : m_blobURLs)3994 cost += urls.sizeInBytes();3989 for (auto& handle : m_blobHandles) 3990 cost += handle.url().string().sizeInBytes(); 3995 3991 3996 3992 return cost; … … 4070 4066 { 4071 4067 Vector<uint8_t> buffer; 4072 Vector< String> blobURLs;4068 Vector<Blob::Handle> blobHandles; 4073 4069 Vector<RefPtr<MessagePort>> dummyMessagePorts; 4074 4070 Vector<RefPtr<ImageBitmap>> dummyImageBitmaps; … … 4096 4092 dummyMemoryHandles, 4097 4093 #endif 4098 blob URLs, buffer, SerializationContext::Default, dummySharedBuffers);4094 blobHandles, buffer, SerializationContext::Default, dummySharedBuffers); 4099 4095 4100 4096 #if ENABLE(WEBASSEMBLY) … … 4109 4105 return nullptr; 4110 4106 4111 return adoptRef(*new SerializedScriptValue(WTFMove(buffer), blob URLs, nullptr, nullptr, { }));4107 return adoptRef(*new SerializedScriptValue(WTFMove(buffer), blobHandles, nullptr, nullptr, { })); 4112 4108 } 4113 4109 … … 4222 4218 4223 4219 Vector<uint8_t> buffer; 4224 Vector< String> blobURLs;4220 Vector<Blob::Handle> blobHandles; 4225 4221 #if ENABLE(WEBASSEMBLY) 4226 4222 WasmModuleArray wasmModules; … … 4239 4235 wasmMemoryHandles, 4240 4236 #endif 4241 blob URLs, buffer, context, *sharedBuffers);4237 blobHandles, buffer, context, *sharedBuffers); 4242 4238 4243 4239 if (code != SerializationReturnCode::SuccessfullyCompleted) … … 4261 4257 #endif 4262 4258 4263 return adoptRef(*new SerializedScriptValue(WTFMove(buffer), blob URLs, arrayBufferContentsArray.releaseReturnValue(), context == SerializationContext::WorkerPostMessage ? WTFMove(sharedBuffers) : nullptr, WTFMove(backingStores)4259 return adoptRef(*new SerializedScriptValue(WTFMove(buffer), blobHandles, arrayBufferContentsArray.releaseReturnValue(), context == SerializationContext::WorkerPostMessage ? WTFMove(sharedBuffers) : nullptr, WTFMove(backingStores) 4264 4260 #if ENABLE(OFFSCREEN_CANVAS_IN_WORKERS) 4265 4261 , WTFMove(detachedCanvases) … … 4367 4363 } 4368 4364 4369 Vector<String> SerializedScriptValue::blobURLs IsolatedCopy() const4365 Vector<String> SerializedScriptValue::blobURLs() const 4370 4366 { 4371 4367 Vector<String> result; 4372 result.reserveInitialCapacity(m_blob URLs.size());4373 for (auto& url : m_blobURLs)4374 result.uncheckedAppend( url.isolatedCopy());4368 result.reserveInitialCapacity(m_blobHandles.size()); 4369 for (auto& handle : m_blobHandles) 4370 result.uncheckedAppend(handle.url().string()); 4375 4371 4376 4372 return result; … … 4382 4378 ASSERT(hasBlobURLs()); 4383 4379 4384 blobRegistry().writeBlobsToTemporaryFiles( m_blobURLs, [completionHandler = WTFMove(completionHandler), this, protectedThis = makeRef(*this)] (auto&& blobFilePaths) mutable {4380 blobRegistry().writeBlobsToTemporaryFiles(blobURLs(), [completionHandler = WTFMove(completionHandler), this, protectedThis = makeRef(*this)] (auto&& blobFilePaths) mutable { 4385 4381 ASSERT(isMainThread()); 4386 4382 … … 4392 4388 } 4393 4389 4394 ASSERT(m_blob URLs.size() == blobFilePaths.size());4395 4396 completionHandler({ *this, m_blobURLs, blobFilePaths });4390 ASSERT(m_blobHandles.size() == blobFilePaths.size()); 4391 4392 completionHandler({ *this, blobURLs(), blobFilePaths }); 4397 4393 }); 4398 4394 } -
trunk/Source/WebCore/bindings/js/SerializedScriptValue.h
r278253 r280547 27 27 #pragma once 28 28 29 #include "Blob.h" 29 30 #include "DetachedRTCDataChannel.h" 30 31 #include "ExceptionOr.h" … … 96 97 97 98 const Vector<uint8_t>& data() const { return m_data; } 98 bool hasBlobURLs() const { return !m_blobURLs.isEmpty(); } 99 100 Vector<String> blobURLsIsolatedCopy() const; 99 bool hasBlobURLs() const { return !m_blobHandles.isEmpty(); } 100 101 Vector<String> blobURLs() const; 102 const Vector<Blob::Handle>& blobHandles() const { return m_blobHandles; } 101 103 void writeBlobsToDiskForIndexedDB(CompletionHandler<void(IDBValue&&)>&&); 102 104 IDBValue writeBlobsToDiskForIndexedDBSynchronously(); … … 122 124 ); 123 125 124 SerializedScriptValue(Vector<unsigned char>&&, const Vector< String>& blobURLs, std::unique_ptr<ArrayBufferContentsArray>, std::unique_ptr<ArrayBufferContentsArray> sharedBuffers, Vector<std::optional<ImageBitmapBacking>>&& backingStores126 SerializedScriptValue(Vector<unsigned char>&&, const Vector<Blob::Handle>& blobHandles, std::unique_ptr<ArrayBufferContentsArray>, std::unique_ptr<ArrayBufferContentsArray> sharedBuffers, Vector<std::optional<ImageBitmapBacking>>&& backingStores 125 127 #if ENABLE(OFFSCREEN_CANVAS_IN_WORKERS) 126 128 , Vector<std::unique_ptr<DetachedOffscreenCanvas>>&& = { } … … 151 153 std::unique_ptr<WasmMemoryHandleArray> m_wasmMemoryHandlesArray; 152 154 #endif 153 Vector< String> m_blobURLs;155 Vector<Blob::Handle> m_blobHandles; 154 156 size_t m_memoryCost { 0 }; 155 157 }; -
trunk/Source/WebCore/dom/BroadcastChannel.cpp
r279971 r280547 35 35 #include "WorkerGlobalScope.h" 36 36 #include "WorkerLoaderProxy.h" 37 #include <wtf/CallbackAggregator.h> 37 38 #include <wtf/HashMap.h> 38 39 #include <wtf/IsoMallocInlines.h> … … 96 97 97 98 ensureOnMainThread([origin = crossThreadCopy(m_origin), name = crossThreadCopy(m_name), identifier = m_identifier, messageData = messageData.releaseReturnValue()](auto& document) mutable { 98 if (auto* page = document.page()) 99 page->broadcastChannelRegistry().postMessage(origin, name, identifier, WTFMove(messageData)); 99 auto* page = document.page(); 100 if (!page) 101 return; 102 103 auto blobHandles = messageData->blobHandles(); 104 page->broadcastChannelRegistry().postMessage(origin, name, identifier, WTFMove(messageData), [blobHandles = WTFMove(blobHandles)] { 105 // Keeps Blob data inside messageData alive until the message has been delivered. 106 }); 100 107 }); 101 108 … … 116 123 } 117 124 118 void BroadcastChannel::dispatchMessageTo(BroadcastChannelIdentifier channelIdentifier, Ref<SerializedScriptValue>&& message )125 void BroadcastChannel::dispatchMessageTo(BroadcastChannelIdentifier channelIdentifier, Ref<SerializedScriptValue>&& message, CompletionHandler<void()>&& completionHandler) 119 126 { 120 127 ASSERT(isMainThread()); 121 128 auto contextIdentifier = channelToContextIdentifier().get(channelIdentifier); 122 129 if (!contextIdentifier) 123 return ;130 return completionHandler(); 124 131 125 ScriptExecutionContext::postTaskTo(contextIdentifier, [channelIdentifier, message = WTFMove(message)](auto&) mutable { 132 auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler)); 133 ScriptExecutionContext::postTaskTo(contextIdentifier, [channelIdentifier, message = WTFMove(message), callbackAggregator = WTFMove(callbackAggregator)](auto&) mutable { 126 134 RefPtr<BroadcastChannel> channel; 127 135 { … … 131 139 if (channel) 132 140 channel->dispatchMessage(WTFMove(message)); 141 142 callOnMainThread([callbackAggregator = WTFMove(callbackAggregator)] { }); 133 143 }); 134 144 } -
trunk/Source/WebCore/dom/BroadcastChannel.h
r279971 r280547 63 63 void close(); 64 64 65 WEBCORE_EXPORT static void dispatchMessageTo(BroadcastChannelIdentifier, Ref<SerializedScriptValue>&& );65 WEBCORE_EXPORT static void dispatchMessageTo(BroadcastChannelIdentifier, Ref<SerializedScriptValue>&&, CompletionHandler<void()>&&); 66 66 67 67 private: -
trunk/Source/WebCore/dom/BroadcastChannelRegistry.h
r279971 r280547 27 27 28 28 #include "BroadcastChannelIdentifier.h" 29 #include <wtf/Forward.h> 29 30 #include <wtf/RefCounted.h> 30 31 … … 39 40 virtual void registerChannel(const SecurityOriginData&, const String& name, BroadcastChannelIdentifier) = 0; 40 41 virtual void unregisterChannel(const SecurityOriginData&, const String& name, BroadcastChannelIdentifier) = 0; 41 virtual void postMessage(const SecurityOriginData&, const String& name, BroadcastChannelIdentifier source, Ref<SerializedScriptValue>&& ) = 0;42 virtual void postMessage(const SecurityOriginData&, const String& name, BroadcastChannelIdentifier source, Ref<SerializedScriptValue>&&, CompletionHandler<void()>&&) = 0; 42 43 }; 43 44 -
trunk/Source/WebCore/fileapi/Blob.cpp
r278702 r280547 45 45 #include <wtf/IsoMallocInlines.h> 46 46 #include <wtf/NeverDestroyed.h> 47 #include <wtf/ThreadSafeRefCounted.h> 47 48 #include <wtf/text/CString.h> 48 49 … … 59 60 }; 60 61 61 62 62 void BlobURLRegistry::registerURL(ScriptExecutionContext& context, const URL& publicURL, URLRegistrable& blob) 63 63 { … … 77 77 } 78 78 79 // Unregisters the Blob's internal URL upon destruction. This can be used to extend the lifetime of the Blob data 80 // without actually keeping the Blob object alive. 81 class BlobInternalURL : public ThreadSafeRefCounted<BlobInternalURL> { 82 public: 83 static Ref<BlobInternalURL> create(Vector<BlobPart>&& blobParts, const String& contentType) 84 { 85 return adoptRef(*new BlobInternalURL(WTFMove(blobParts), contentType)); 86 } 87 88 static Ref<BlobInternalURL> createForDeserialization(const URL& sourceURL, const String& fileBackedPath, const String& type) 89 { 90 return adoptRef(*new BlobInternalURL(sourceURL, fileBackedPath, type)); 91 } 92 93 static Ref<BlobInternalURL> createForSlice(const URL& sourceURL, long long start, long long end, const String& type) 94 { 95 return adoptRef(*new BlobInternalURL(sourceURL, start, end, type)); 96 } 97 98 static Ref<BlobInternalURL> adoptInternalURL(const URL& url) 99 { 100 return adoptRef(*new BlobInternalURL(crossThreadCopy(url))); 101 } 102 103 ~BlobInternalURL() 104 { 105 ThreadableBlobRegistry::unregisterBlobURL(m_internalURL); 106 } 107 108 URL url() const { return m_internalURL.isolatedCopy(); } 109 110 private: 111 BlobInternalURL(Vector<BlobPart>&& blobParts, const String& contentType) 112 : m_internalURL(BlobURL::createInternalURL()) 113 { 114 ThreadableBlobRegistry::registerBlobURL(m_internalURL, WTFMove(blobParts), contentType); 115 } 116 BlobInternalURL(const URL& sourceURL, long long start, long long end, const String& type) 117 : m_internalURL(BlobURL::createInternalURL()) 118 { 119 ThreadableBlobRegistry::registerBlobURLForSlice(m_internalURL, sourceURL, start, end, type); 120 } 121 BlobInternalURL(const URL& sourceURL, const String& fileBackedPath, const String& type) 122 : m_internalURL(BlobURL::createInternalURL()) 123 { 124 if (fileBackedPath.isEmpty()) 125 ThreadableBlobRegistry::registerBlobURL(nullptr, m_internalURL, sourceURL); 126 else 127 ThreadableBlobRegistry::registerBlobURLOptionallyFileBacked(m_internalURL, sourceURL, fileBackedPath, type); 128 } 129 BlobInternalURL(URL&& internalURL) 130 : m_internalURL(WTFMove(internalURL)) 131 { } 132 133 URL m_internalURL; 134 }; 135 79 136 Blob::Blob(UninitializedContructor, ScriptExecutionContext* context, URL&& url, String&& type) 80 137 : ActiveDOMObject(context) 81 , m_internalURL(WTFMove(url))82 138 , m_type(WTFMove(type)) 139 , m_internalURL(BlobInternalURL::adoptInternalURL(url)) 83 140 { 84 141 } … … 87 144 : ActiveDOMObject(context) 88 145 , m_size(0) 89 { 90 m_internalURL = BlobURL::createInternalURL(); 91 ThreadableBlobRegistry::registerBlobURL(m_internalURL, { }, { }); 92 } 93 94 Blob::Blob(ScriptExecutionContext& context, Vector<BlobPartVariant>&& blobPartVariants, const BlobPropertyBag& propertyBag) 95 : ActiveDOMObject(&context) 96 , m_internalURL(BlobURL::createInternalURL()) 97 , m_type(normalizedContentType(propertyBag.type)) 146 , m_internalURL(BlobInternalURL::create({ }, { })) 147 { 148 } 149 150 static Vector<BlobPart> buildBlobData(Vector<BlobPartVariant>&& blobPartVariants, const BlobPropertyBag& propertyBag) 98 151 { 99 152 BlobBuilder builder(propertyBag.endings); … … 105 158 ); 106 159 } 107 108 ThreadableBlobRegistry::registerBlobURL(m_internalURL, builder.finalize(), m_type); 160 return builder.finalize(); 161 } 162 163 Blob::Blob(ScriptExecutionContext& context, Vector<BlobPartVariant>&& blobPartVariants, const BlobPropertyBag& propertyBag) 164 : ActiveDOMObject(&context) 165 , m_type(normalizedContentType(propertyBag.type)) 166 , m_internalURL(BlobInternalURL::create(buildBlobData(WTFMove(blobPartVariants), propertyBag), m_type)) 167 { 109 168 } 110 169 … … 113 172 , m_type(contentType) 114 173 , m_size(data.size()) 115 { 116 Vector<BlobPart> blobParts; 117 blobParts.append(BlobPart(WTFMove(data))); 118 m_internalURL = BlobURL::createInternalURL(); 119 ThreadableBlobRegistry::registerBlobURL(m_internalURL, WTFMove(blobParts), contentType); 174 , m_internalURL(BlobInternalURL::create({ BlobPart(WTFMove(data)) }, contentType)) 175 { 120 176 } 121 177 122 178 Blob::Blob(ReferencingExistingBlobConstructor, ScriptExecutionContext* context, const Blob& blob) 123 179 : ActiveDOMObject(context) 124 , m_internalURL(BlobURL::createInternalURL())125 180 , m_type(blob.type()) 126 181 , m_size(blob.size()) 127 { 128 ThreadableBlobRegistry::registerBlobURL(m_internalURL, { BlobPart(blob.url()) } , m_type); 182 , m_internalURL(BlobInternalURL::create({ BlobPart(blob.url()) } , m_type)) 183 { 129 184 } 130 185 … … 133 188 , m_type(normalizedContentType(type)) 134 189 , m_size(size) 135 { 136 m_internalURL = BlobURL::createInternalURL(); 137 if (fileBackedPath.isEmpty()) 138 ThreadableBlobRegistry::registerBlobURL(nullptr, m_internalURL, srcURL); 139 else 140 ThreadableBlobRegistry::registerBlobURLOptionallyFileBacked(m_internalURL, srcURL, fileBackedPath, m_type); 190 , m_internalURL(BlobInternalURL::createForDeserialization(srcURL, fileBackedPath, m_type)) 191 { 141 192 } 142 193 … … 144 195 : ActiveDOMObject(context) 145 196 , m_type(normalizedContentType(type)) 197 , m_internalURL(BlobInternalURL::createForSlice(srcURL, start, end, m_type)) 146 198 // m_size is not necessarily equal to end - start so we do not initialize it here. 147 199 { 148 m_internalURL = BlobURL::createInternalURL();149 ThreadableBlobRegistry::registerBlobURLForSlice(m_internalURL, srcURL, start, end, m_type);150 200 } 151 201 … … 154 204 while (!m_blobLoaders.isEmpty()) 155 205 (*m_blobLoaders.begin())->cancel(); 156 157 ThreadableBlobRegistry::unregisterBlobURL(m_internalURL); 206 } 207 208 URL Blob::url() const 209 { 210 return m_internalURL->url(); 211 } 212 213 Ref<Blob> Blob::slice(ScriptExecutionContext& context, long long start, long long end, const String& contentType) const 214 { 215 auto blob = adoptRef(*new Blob(&context, m_internalURL->url(), start, end, contentType)); 216 blob->suspendIfNeeded(); 217 return blob; 158 218 } 159 219 … … 163 223 // FIXME: JavaScript cannot represent sizes as large as unsigned long long, we need to 164 224 // come up with an exception to throw if file size is not representable. 165 unsigned long long actualSize = ThreadableBlobRegistry::blobSize(m_internalURL );225 unsigned long long actualSize = ThreadableBlobRegistry::blobSize(m_internalURL->url()); 166 226 m_size = isInBounds<long long>(actualSize) ? actualSize : 0; 167 227 } … … 336 396 } 337 397 398 Blob::Handle Blob::handle() const 399 { 400 return Handle { m_internalURL.copyRef() }; 401 } 402 403 Blob::Handle::Handle(Ref<BlobInternalURL>&& internalURL) 404 : m_internalURL(WTFMove(internalURL)) 405 { } 406 407 Blob::Handle::~Handle() = default; 408 409 Blob::Handle::Handle(Handle&&) = default; 410 Blob::Handle::Handle(const Handle&) = default; 411 412 URL Blob::Handle::url() const 413 { 414 return m_internalURL->url(); 415 } 338 416 339 417 } // namespace WebCore -
trunk/Source/WebCore/fileapi/Blob.h
r278702 r280547 58 58 59 59 using BlobPartVariant = Variant<RefPtr<JSC::ArrayBufferView>, RefPtr<JSC::ArrayBuffer>, RefPtr<Blob>, String>; 60 class BlobInternalURL; 60 61 61 62 class Blob : public ScriptWrappable, public URLRegistrable, public RefCounted<Blob>, public ActiveDOMObject { … … 93 94 virtual ~Blob(); 94 95 95 const URL& url() const { return m_internalURL; }96 WEBCORE_EXPORT URL url() const; 96 97 const String& type() const { return m_type; } 97 98 … … 111 112 URLRegistry& registry() const override; 112 113 113 Ref<Blob> slice(ScriptExecutionContext& context, long long start, long long end, const String& contentType) const 114 { 115 auto blob = adoptRef(*new Blob(&context, m_internalURL, start, end, contentType)); 116 blob->suspendIfNeeded(); 117 return blob; 118 } 114 Ref<Blob> slice(ScriptExecutionContext&, long long start, long long end, const String& contentType) const; 119 115 120 116 void text(ScriptExecutionContext&, Ref<DeferredPromise>&&); 121 117 void arrayBuffer(ScriptExecutionContext&, Ref<DeferredPromise>&&); 122 118 ExceptionOr<Ref<ReadableStream>> stream(ScriptExecutionContext&); 119 120 class Handle { 121 public: 122 explicit Handle(Ref<BlobInternalURL>&&); 123 ~Handle(); 124 Handle(Handle&&); 125 Handle(const Handle&); 126 URL url() const; 127 private: 128 Ref<BlobInternalURL> m_internalURL; 129 }; 130 131 // Keeping the handle alive will keep the Blob data alive (but not the Blob object). 132 Handle handle() const; 123 133 124 134 protected: … … 145 155 const char* activeDOMObjectName() const override; 146 156 157 String m_type; 158 mutable std::optional<unsigned long long> m_size; 159 147 160 // This is an internal URL referring to the blob data associated with this object. It serves 148 161 // as an identifier for this blob. The internal URL is never used to source the blob's content 149 162 // into an HTML or for FileRead'ing, public blob URLs must be used for those purposes. 150 URLm_internalURL;163 Ref<BlobInternalURL> m_internalURL; 151 164 152 String m_type;153 154 mutable std::optional<unsigned long long> m_size;155 165 HashSet<std::unique_ptr<BlobLoader>> m_blobLoaders; 156 166 }; -
trunk/Source/WebCore/loader/EmptyClients.cpp
r280053 r280547 1176 1176 void registerChannel(const SecurityOriginData&, const String&, BroadcastChannelIdentifier) final { } 1177 1177 void unregisterChannel(const SecurityOriginData&, const String&, BroadcastChannelIdentifier) final { } 1178 void postMessage(const SecurityOriginData&, const String&, BroadcastChannelIdentifier, Ref<SerializedScriptValue>&& ) final { }1178 void postMessage(const SecurityOriginData&, const String&, BroadcastChannelIdentifier, Ref<SerializedScriptValue>&&, CompletionHandler<void()>&&) final { } 1179 1179 }; 1180 1180 -
trunk/Source/WebKit/ChangeLog
r280542 r280547 1 2021-08-02 Chris Dumez <cdumez@apple.com> 2 3 imported/w3c/web-platform-tests/webmessaging/broadcastchannel/blobs.html is a flaky failure since implementing BlobChannel 4 https://bugs.webkit.org/show_bug.cgi?id=228168 5 <rdar://problem/80922502> 6 7 Reviewed by Alex Christensen. 8 9 * NetworkProcess/NetworkBroadcastChannelRegistry.cpp: 10 (WebKit::NetworkBroadcastChannelRegistry::postMessage): 11 * NetworkProcess/NetworkBroadcastChannelRegistry.h: 12 * NetworkProcess/NetworkBroadcastChannelRegistry.messages.in: 13 14 * Platform/IPC/HandleMessage.h: 15 (IPC::handleMessageAsyncWantsConnection): 16 handleMessageAsyncWantsConnection() had gotten out of sync with handleMessageAsync(). This was causing IPC decoding 17 failures when using both "Async" and "WantsConnection" for the IPC message. 18 19 * WebProcess/WebCoreSupport/WebBroadcastChannelRegistry.cpp: 20 (WebKit::WebBroadcastChannelRegistry::postMessage): 21 (WebKit::WebBroadcastChannelRegistry::postMessageToRemote): 22 * WebProcess/WebCoreSupport/WebBroadcastChannelRegistry.h: 23 * WebProcess/WebCoreSupport/WebBroadcastChannelRegistry.messages.in: 24 1 25 2021-08-02 Per Arne Vollan <pvollan@apple.com> 2 26 -
trunk/Source/WebKit/NetworkProcess/NetworkBroadcastChannelRegistry.cpp
r280419 r280547 29 29 #include "WebBroadcastChannelRegistryMessages.h" 30 30 #include <WebCore/MessageWithMessagePorts.h> 31 #include <wtf/CallbackAggregator.h> 31 32 32 33 namespace WebKit { … … 59 60 } 60 61 61 void NetworkBroadcastChannelRegistry::postMessage(IPC::Connection& connection, const WebCore::SecurityOriginData& origin, const String& name, WebCore::BroadcastChannelIdentifier source, WebCore::MessageWithMessagePorts&& message )62 void NetworkBroadcastChannelRegistry::postMessage(IPC::Connection& connection, const WebCore::SecurityOriginData& origin, const String& name, WebCore::BroadcastChannelIdentifier source, WebCore::MessageWithMessagePorts&& message, CompletionHandler<void()>&& completionHandler) 62 63 { 63 64 auto channelsForOriginIterator = m_broadcastChannels.find(origin); 64 65 ASSERT(channelsForOriginIterator != m_broadcastChannels.end()); 65 66 if (channelsForOriginIterator == m_broadcastChannels.end()) 66 return ;67 return completionHandler(); 67 68 auto channelsForNameIterator = channelsForOriginIterator->value.find(name); 68 69 ASSERT(channelsForNameIterator != channelsForOriginIterator->value.end()); 69 70 if (channelsForNameIterator == channelsForOriginIterator->value.end()) 70 return ;71 return completionHandler(); 71 72 73 auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler)); 72 74 GlobalBroadcastChannelIdentifier sourceGlobalChannelIdentifier { connection.uniqueID(), source }; 73 75 for (auto& globalIdentifier : channelsForNameIterator->value) { … … 75 77 continue; 76 78 77 IPC::Connection::send(globalIdentifier.connectionIdentifier, Messages::WebBroadcastChannelRegistry::PostMessageToRemote(globalIdentifier.channelIndentifierInProcess, message), 0); 79 RefPtr connection = IPC::Connection::connection(globalIdentifier.connectionIdentifier); 80 if (!connection) 81 continue; 82 83 connection->sendWithAsyncReply(Messages::WebBroadcastChannelRegistry::PostMessageToRemote(globalIdentifier.channelIndentifierInProcess, message), [callbackAggregator] { }, 0); 78 84 } 79 85 } -
trunk/Source/WebKit/NetworkProcess/NetworkBroadcastChannelRegistry.h
r279971 r280547 48 48 void registerChannel(IPC::Connection&, const WebCore::SecurityOriginData&, const String& name, WebCore::BroadcastChannelIdentifier); 49 49 void unregisterChannel(IPC::Connection&, const WebCore::SecurityOriginData&, const String& name, WebCore::BroadcastChannelIdentifier); 50 void postMessage(IPC::Connection&, const WebCore::SecurityOriginData&, const String& name, WebCore::BroadcastChannelIdentifier source, WebCore::MessageWithMessagePorts&& );50 void postMessage(IPC::Connection&, const WebCore::SecurityOriginData&, const String& name, WebCore::BroadcastChannelIdentifier source, WebCore::MessageWithMessagePorts&&, CompletionHandler<void()>&&); 51 51 52 52 private: -
trunk/Source/WebKit/NetworkProcess/NetworkBroadcastChannelRegistry.messages.in
r279971 r280547 24 24 RegisterChannel(struct WebCore::SecurityOriginData origin, String name, WebCore::BroadcastChannelIdentifier channelIdentifier) WantsConnection 25 25 UnregisterChannel(struct WebCore::SecurityOriginData origin, String name, WebCore::BroadcastChannelIdentifier channelIdentifier) WantsConnection 26 PostMessage(struct WebCore::SecurityOriginData origin, String name, WebCore::BroadcastChannelIdentifier source, struct WebCore::MessageWithMessagePorts message) WantsConnection26 PostMessage(struct WebCore::SecurityOriginData origin, String name, WebCore::BroadcastChannelIdentifier source, struct WebCore::MessageWithMessagePorts message) -> () Async WantsConnection 27 27 } -
trunk/Source/WebKit/Platform/IPC/HandleMessage.h
r278253 r280547 201 201 void handleMessageAsyncWantsConnection(Connection& connection, Decoder& decoder, C* object, MF function) 202 202 { 203 std::optional<typename CodingType<typename T::Arguments>::Type> arguments; 204 decoder >> arguments; 205 if (UNLIKELY(!arguments)) 206 return; 207 208 typename T::AsyncReply completionHandler = [listenerID = decoder.destinationID(), connection = makeRef(connection)] (auto&&... args) mutable { 203 std::optional<uint64_t> listenerID; 204 decoder >> listenerID; 205 if (!listenerID) 206 return; 207 208 std::optional<typename CodingType<typename T::Arguments>::Type> arguments; 209 decoder >> arguments; 210 if (UNLIKELY(!arguments)) 211 return; 212 213 typename T::AsyncReply completionHandler = { [listenerID = *listenerID, connection = makeRef(connection)] (auto&&... args) mutable { 209 214 auto encoder = makeUniqueRef<Encoder>(T::asyncMessageReplyName(), listenerID); 210 215 T::send(WTFMove(encoder), WTFMove(connection), args...); 211 } ;216 }, T::callbackThread }; 212 217 callMemberFunction(connection, WTFMove(*arguments), WTFMove(completionHandler), object, function); 213 218 } -
trunk/Source/WebKit/WebProcess/WebCoreSupport/WebBroadcastChannelRegistry.cpp
r279971 r280547 50 50 } 51 51 52 void WebBroadcastChannelRegistry::postMessage(const WebCore::SecurityOriginData& origin, const String& name, WebCore::BroadcastChannelIdentifier source, Ref<WebCore::SerializedScriptValue>&& message )52 void WebBroadcastChannelRegistry::postMessage(const WebCore::SecurityOriginData& origin, const String& name, WebCore::BroadcastChannelIdentifier source, Ref<WebCore::SerializedScriptValue>&& message, CompletionHandler<void()>&& completionHandler) 53 53 { 54 networkProcessConnection().send (Messages::NetworkBroadcastChannelRegistry::PostMessage { origin, name, source, WebCore::MessageWithMessagePorts { WTFMove(message), { } } }, 0);54 networkProcessConnection().sendWithAsyncReply(Messages::NetworkBroadcastChannelRegistry::PostMessage { origin, name, source, WebCore::MessageWithMessagePorts { WTFMove(message), { } } }, WTFMove(completionHandler), 0); 55 55 } 56 56 57 void WebBroadcastChannelRegistry::postMessageToRemote(WebCore::BroadcastChannelIdentifier identifier, WebCore::MessageWithMessagePorts&& message )57 void WebBroadcastChannelRegistry::postMessageToRemote(WebCore::BroadcastChannelIdentifier identifier, WebCore::MessageWithMessagePorts&& message, CompletionHandler<void()>&& completionHandler) 58 58 { 59 WebCore::BroadcastChannel::dispatchMessageTo(identifier, message.message.releaseNonNull() );59 WebCore::BroadcastChannel::dispatchMessageTo(identifier, message.message.releaseNonNull(), WTFMove(completionHandler)); 60 60 } 61 61 -
trunk/Source/WebKit/WebProcess/WebCoreSupport/WebBroadcastChannelRegistry.h
r279971 r280547 44 44 void registerChannel(const WebCore::SecurityOriginData&, const String& name, WebCore::BroadcastChannelIdentifier) final; 45 45 void unregisterChannel(const WebCore::SecurityOriginData&, const String& name, WebCore::BroadcastChannelIdentifier) final; 46 void postMessage(const WebCore::SecurityOriginData&, const String& name, WebCore::BroadcastChannelIdentifier source, Ref<WebCore::SerializedScriptValue>&& ) final;46 void postMessage(const WebCore::SecurityOriginData&, const String& name, WebCore::BroadcastChannelIdentifier source, Ref<WebCore::SerializedScriptValue>&&, CompletionHandler<void()>&&) final; 47 47 48 48 void didReceiveMessage(IPC::Connection&, IPC::Decoder&); … … 51 51 WebBroadcastChannelRegistry() = default; 52 52 53 void postMessageToRemote(WebCore::BroadcastChannelIdentifier, WebCore::MessageWithMessagePorts&& );53 void postMessageToRemote(WebCore::BroadcastChannelIdentifier, WebCore::MessageWithMessagePorts&&, CompletionHandler<void()>&&); 54 54 }; 55 55 -
trunk/Source/WebKit/WebProcess/WebCoreSupport/WebBroadcastChannelRegistry.messages.in
r279971 r280547 22 22 23 23 messages -> WebBroadcastChannelRegistry { 24 PostMessageToRemote(WebCore::BroadcastChannelIdentifier destination, struct WebCore::MessageWithMessagePorts message) 24 PostMessageToRemote(WebCore::BroadcastChannelIdentifier destination, struct WebCore::MessageWithMessagePorts message) -> () Async 25 25 } -
trunk/Source/WebKitLegacy/ChangeLog
r280053 r280547 1 2021-08-02 Chris Dumez <cdumez@apple.com> 2 3 imported/w3c/web-platform-tests/webmessaging/broadcastchannel/blobs.html is a flaky failure since implementing BlobChannel 4 https://bugs.webkit.org/show_bug.cgi?id=228168 5 <rdar://problem/80922502> 6 7 Reviewed by Alex Christensen. 8 9 * WebCoreSupport/WebBroadcastChannelRegistry.cpp: 10 (WebBroadcastChannelRegistry::postMessage): 11 * WebCoreSupport/WebBroadcastChannelRegistry.h: 12 1 13 2021-07-19 Sihui Liu <sihui_liu@apple.com> 2 14 -
trunk/Source/WebKitLegacy/WebCoreSupport/WebBroadcastChannelRegistry.cpp
r279971 r280547 28 28 #include <WebCore/BroadcastChannel.h> 29 29 #include <WebCore/SerializedScriptValue.h> 30 #include <wtf/CallbackAggregator.h> 30 31 #include <wtf/HashMap.h> 31 32 #include <wtf/NeverDestroyed.h> … … 66 67 } 67 68 68 void WebBroadcastChannelRegistry::postMessage(const WebCore::SecurityOriginData& origin, const String& name, WebCore::BroadcastChannelIdentifier source, Ref<WebCore::SerializedScriptValue>&& message )69 void WebBroadcastChannelRegistry::postMessage(const WebCore::SecurityOriginData& origin, const String& name, WebCore::BroadcastChannelIdentifier source, Ref<WebCore::SerializedScriptValue>&& message, CompletionHandler<void()>&& completionHandler) 69 70 { 70 71 ASSERT(isMainThread()); 72 auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler)); 73 71 74 auto channelsForOriginIterator = m_channels.find(origin); 72 75 ASSERT(channelsForOriginIterator != m_channels.end()); … … 79 82 if (channelIdentifier == source) 80 83 continue; 81 WebCore::BroadcastChannel::dispatchMessageTo(channelIdentifier, message.copyRef() );84 WebCore::BroadcastChannel::dispatchMessageTo(channelIdentifier, message.copyRef(), [callbackAggregator] { }); 82 85 } 83 86 } -
trunk/Source/WebKitLegacy/WebCoreSupport/WebBroadcastChannelRegistry.h
r279971 r280547 37 37 void registerChannel(const WebCore::SecurityOriginData&, const String& name, WebCore::BroadcastChannelIdentifier) final; 38 38 void unregisterChannel(const WebCore::SecurityOriginData&, const String& name, WebCore::BroadcastChannelIdentifier) final; 39 void postMessage(const WebCore::SecurityOriginData&, const String& name, WebCore::BroadcastChannelIdentifier source, Ref<WebCore::SerializedScriptValue>&& ) final;39 void postMessage(const WebCore::SecurityOriginData&, const String& name, WebCore::BroadcastChannelIdentifier source, Ref<WebCore::SerializedScriptValue>&&, CompletionHandler<void()>&&) final; 40 40 41 41 private:
Note:
See TracChangeset
for help on using the changeset viewer.