Changeset 249481 in webkit
- Timestamp:
- Sep 4, 2019 9:46:55 AM (5 years ago)
- Location:
- trunk/Source
- Files:
-
- 3 added
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r249480 r249481 1 2019-09-04 Youenn Fablet <youenn@apple.com> 2 3 Abstract out WebSocketChannel message queue 4 https://bugs.webkit.org/show_bug.cgi?id=201359 5 6 Reviewed by Alex Christensen. 7 8 Move BlobLoader in its own file. 9 Introduce NetworkSendQueue class to handle the sending of messages, some of them being blobs. 10 This class ensures that messages will be sent in order, even though blob data is resolved asynchronously. 11 12 Covered by existing tests. 13 14 * Headers.cmake: 15 * Sources.txt: 16 * WebCore.xcodeproj/project.pbxproj: 17 * fileapi/BlobLoader.h: Added. 18 (WebCore::BlobLoader::BlobLoader): 19 (WebCore::BlobLoader::~BlobLoader): 20 (WebCore::BlobLoader::didFinishLoading): 21 (WebCore::BlobLoader::didFail): 22 (WebCore::BlobLoader::complete): 23 * fileapi/NetworkSendQueue.cpp: Added. 24 (WebCore::NetworkSendQueue::NetworkSendQueue): 25 (WebCore::NetworkSendQueue::enqueue): 26 (WebCore::NetworkSendQueue::clear): 27 (WebCore::NetworkSendQueue::processMessages): 28 * fileapi/NetworkSendQueue.h: Added. 29 1 30 2019-09-04 Rob Buis <rbuis@igalia.com> 2 31 -
trunk/Source/WebCore/Headers.cmake
r249217 r249481 520 520 fileapi/FileReaderLoader.h 521 521 fileapi/FileReaderLoaderClient.h 522 fileapi/NetworkSendQueue.h 522 523 523 524 history/BackForwardClient.h -
trunk/Source/WebCore/Sources.txt
r249378 r249481 1057 1057 fileapi/FileReaderLoader.cpp 1058 1058 fileapi/FileReaderSync.cpp 1059 fileapi/NetworkSendQueue.cpp 1059 1060 fileapi/ThreadableBlobRegistry.cpp 1060 1061 -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r249379 r249481 1124 1124 41DEFCB61E56C1BD000D9E5F /* JSDOMMapLike.h in Headers */ = {isa = PBXBuildFile; fileRef = 41DEFCB41E56C1B9000D9E5F /* JSDOMMapLike.h */; }; 1125 1125 41E1B1D10FF5986900576B3B /* AbstractWorker.h in Headers */ = {isa = PBXBuildFile; fileRef = 41E1B1CB0FF5986900576B3B /* AbstractWorker.h */; }; 1126 41E9DCE7231974BF00F35949 /* BlobLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 41E9DCE4231973FE00F35949 /* BlobLoader.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1127 41E9DCE92319CA7600F35949 /* NetworkSendQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 41E9DCE82319CA7500F35949 /* NetworkSendQueue.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1126 1128 41F062140F5F192600A07EAC /* InspectorDatabaseResource.h in Headers */ = {isa = PBXBuildFile; fileRef = 41F062120F5F192600A07EAC /* InspectorDatabaseResource.h */; }; 1127 1129 41F1D21F0EF35C2A00DA8753 /* ScriptCachedFrameData.h in Headers */ = {isa = PBXBuildFile; fileRef = 41F1D21D0EF35C2A00DA8753 /* ScriptCachedFrameData.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 7387 7389 41E59400214865AA00D3CB61 /* RTCRtpHeaderExtensionParameters.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = RTCRtpHeaderExtensionParameters.idl; sourceTree = "<group>"; }; 7388 7390 41E59401214865AB00D3CB61 /* RTCRtpFecParameters.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = RTCRtpFecParameters.idl; sourceTree = "<group>"; }; 7391 41E9DCE4231973FE00F35949 /* BlobLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BlobLoader.h; sourceTree = "<group>"; }; 7392 41E9DCE62319742300F35949 /* BlobLineEndings.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = BlobLineEndings.idl; sourceTree = "<group>"; }; 7393 41E9DCE82319CA7500F35949 /* NetworkSendQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkSendQueue.h; sourceTree = "<group>"; }; 7394 41E9DCEA2319CAE800F35949 /* NetworkSendQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NetworkSendQueue.cpp; sourceTree = "<group>"; }; 7389 7395 41F062120F5F192600A07EAC /* InspectorDatabaseResource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorDatabaseResource.h; sourceTree = "<group>"; }; 7390 7396 41F062130F5F192600A07EAC /* InspectorDatabaseResource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorDatabaseResource.cpp; sourceTree = "<group>"; }; … … 9731 9737 7C77C3D31DEF178E00A50BFA /* JSBlobPropertyBag.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSBlobPropertyBag.h; sourceTree = "<group>"; }; 9732 9738 7C77C3D61DEF850A00A50BFA /* BlobLineEndings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BlobLineEndings.h; sourceTree = "<group>"; }; 9733 7C77C3D81DEF854000A50BFA /* BlobLineEndings.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = BlobLineEndings.idl; sourceTree = "<group>"; };9734 9739 7C77C3D91DEF86D700A50BFA /* JSBlobLineEndings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSBlobLineEndings.cpp; sourceTree = "<group>"; }; 9735 9740 7C77C3DA1DEF86D700A50BFA /* JSBlobLineEndings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSBlobLineEndings.h; sourceTree = "<group>"; }; … … 21973 21978 A15D75141E68F7B100A35FBC /* BlobCallback.idl */, 21974 21979 7C77C3D61DEF850A00A50BFA /* BlobLineEndings.h */, 21975 7C77C3D81DEF854000A50BFA /* BlobLineEndings.idl */, 21980 41E9DCE62319742300F35949 /* BlobLineEndings.idl */, 21981 41E9DCE4231973FE00F35949 /* BlobLoader.h */, 21976 21982 7C77C3D01DEE472400A50BFA /* BlobPropertyBag.h */, 21977 21983 7C77C3CF1DEE471800A50BFA /* BlobPropertyBag.idl */, … … 21996 22002 2EDF369B122C94B4002F7D4E /* FileReaderSync.h */, 21997 22003 E1AB1EBD14E9E3A800449E13 /* FileReaderSync.idl */, 22004 41E9DCEA2319CAE800F35949 /* NetworkSendQueue.cpp */, 22005 41E9DCE82319CA7500F35949 /* NetworkSendQueue.h */, 21998 22006 976D6C75122B8A3D001FD1F7 /* ThreadableBlobRegistry.cpp */, 21999 22007 976D6C76122B8A3D001FD1F7 /* ThreadableBlobRegistry.h */, … … 28484 28492 4D3B00AF215D6A690076B983 /* BlobEvent.h in Headers */, 28485 28493 7C77C3D71DEF850A00A50BFA /* BlobLineEndings.h in Headers */, 28494 41E9DCE7231974BF00F35949 /* BlobLoader.h in Headers */, 28486 28495 E1C94AF9191303F000D5A893 /* BlobPart.h in Headers */, 28487 28496 7C77C3D11DEE472400A50BFA /* BlobPropertyBag.h in Headers */, … … 30843 30852 8A81BF8511DCFD9000DA2B98 /* NetworkLoadMetrics.h in Headers */, 30844 30853 59C27F07138D28CF0079B7E2 /* NetworkResourcesData.h in Headers */, 30854 41E9DCE92319CA7600F35949 /* NetworkSendQueue.h in Headers */, 30845 30855 1A7FA6190DDA3B3A0028F8A5 /* NetworkStateNotifier.h in Headers */, 30846 30856 E13EF3441684ECF40034C83F /* NetworkStorageSession.h in Headers */, -
trunk/Source/WebKit/ChangeLog
r249479 r249481 1 2019-09-04 Youenn Fablet <youenn@apple.com> 2 3 Abstract out WebSocketChannel message queue 4 https://bugs.webkit.org/show_bug.cgi?id=201359 5 6 Reviewed by Alex Christensen. 7 8 Make use of newly added NetworkSendQueue. 9 10 * WebProcess/Network/WebSocketChannel.cpp: 11 (WebKit::WebSocketChannel::createMessageQueue): 12 (WebKit::WebSocketChannel::WebSocketChannel): 13 (WebKit::WebSocketChannel::send): 14 (WebKit::WebSocketChannel::disconnect): 15 * WebProcess/Network/WebSocketChannel.h: 16 1 17 2019-09-04 Youenn Fablet <youenn@apple.com> 2 18 -
trunk/Source/WebKit/WebProcess/Network/WebSocketChannel.cpp
r248846 r249481 35 35 #include <WebCore/Blob.h> 36 36 #include <WebCore/Document.h> 37 #include <WebCore/FileReaderLoader.h>38 #include <WebCore/FileReaderLoaderClient.h>39 #include <WebCore/NotImplemented.h>40 37 #include <WebCore/WebSocketChannel.h> 41 38 #include <WebCore/WebSocketChannelClient.h> 42 #include <pal/SessionID.h>43 39 #include <wtf/CheckedArithmetic.h> 44 40 41 using namespace WebCore; 42 45 43 namespace WebKit { 46 44 47 Ref<WebSocketChannel> WebSocketChannel::create( WebCore::Document& document, WebCore::WebSocketChannelClient& client)45 Ref<WebSocketChannel> WebSocketChannel::create(Document& document, WebSocketChannelClient& client) 48 46 { 49 47 return adoptRef(*new WebSocketChannel(document, client)); 50 48 } 51 49 52 WebSocketChannel::WebSocketChannel(WebCore::Document& document, WebCore::WebSocketChannelClient& client) 50 NetworkSendQueue WebSocketChannel::createMessageQueue(Document& document, WebSocketChannel& channel) 51 { 52 return { document, [&channel](auto& string) { 53 auto byteLength = string.sizeInBytes(); 54 channel.sendMessage(Messages::NetworkSocketChannel::SendString { string }, byteLength); 55 }, [&channel](const char* data, size_t byteLength) { 56 channel.sendMessage(Messages::NetworkSocketChannel::SendData { IPC::DataReference { reinterpret_cast<const uint8_t*>(data), byteLength } }, byteLength); 57 }, [&channel](auto errorCode) { 58 channel.fail(makeString("Failed to load Blob: error code = ", errorCode)); 59 return NetworkSendQueue::Continue::No; 60 } }; 61 } 62 63 WebSocketChannel::WebSocketChannel(Document& document, WebSocketChannelClient& client) 53 64 : m_document(makeWeakPtr(document)) 54 65 , m_client(makeWeakPtr(client)) 66 , m_messageQueue(createMessageQueue(document, *this)) 55 67 { 56 68 } … … 133 145 } 134 146 135 class BlobLoader final : public WebCore::FileReaderLoaderClient {136 WTF_MAKE_FAST_ALLOCATED;137 public:138 BlobLoader(WebCore::Document* document, WebCore::Blob& blob, CompletionHandler<void()>&& completionHandler)139 : m_loader(makeUnique<WebCore::FileReaderLoader>(WebCore::FileReaderLoader::ReadAsArrayBuffer, this))140 , m_completionHandler(WTFMove(completionHandler))141 {142 m_loader->start(document, blob);143 }144 145 ~BlobLoader()146 {147 if (m_loader)148 m_loader->cancel();149 }150 151 bool isLoading() const { return !!m_loader; }152 const RefPtr<JSC::ArrayBuffer>& result() const { return m_buffer; }153 Optional<int> errorCode() const { return m_errorCode; }154 155 private:156 void didStartLoading() final { }157 void didReceiveData() final { }158 159 void didFinishLoading() final160 {161 m_buffer = m_loader->arrayBufferResult();162 complete();163 }164 165 void didFail(int errorCode) final166 {167 m_errorCode = errorCode;168 complete();169 }170 171 void complete()172 {173 m_loader = nullptr;174 m_completionHandler();175 }176 177 std::unique_ptr<WebCore::FileReaderLoader> m_loader;178 RefPtr<JSC::ArrayBuffer> m_buffer;179 Optional<int> m_errorCode;180 CompletionHandler<void()> m_completionHandler;181 };182 183 class PendingMessage {184 WTF_MAKE_FAST_ALLOCATED;185 public:186 enum class Type { Text, Binary, Blob };187 188 explicit PendingMessage(const String& message)189 : m_type(Type::Text)190 , m_textMessage(message)191 {192 }193 194 PendingMessage(const JSC::ArrayBuffer& binaryData, unsigned byteOffset, unsigned byteLength)195 : m_type(Type::Binary)196 , m_binaryData(WebCore::SharedBuffer::create(static_cast<const uint8_t*>(binaryData.data()) + byteOffset, byteLength))197 {198 }199 200 PendingMessage(WebCore::Document* document, WebCore::Blob& blob, CompletionHandler<void()>&& completionHandler)201 : m_type(Type::Blob)202 , m_blobLoader(makeUnique<BlobLoader>(document, blob, WTFMove(completionHandler)))203 {204 }205 206 ~PendingMessage() = default;207 208 Type type() const { return m_type; }209 const String& textMessage() const { ASSERT(m_type == Type::Text); return m_textMessage; }210 const WebCore::SharedBuffer& binaryData() const { ASSERT(m_type == Type::Binary); return *m_binaryData; }211 const BlobLoader& blobLoader() const { ASSERT(m_type == Type::Blob); return *m_blobLoader; }212 213 private:214 Type m_type;215 String m_textMessage;216 RefPtr<WebCore::SharedBuffer> m_binaryData;217 std::unique_ptr<BlobLoader> m_blobLoader;218 };219 220 147 WebSocketChannel::SendResult WebSocketChannel::send(const String& message) 221 148 { … … 224 151 return SendFail; 225 152 226 if (m_pendingMessages.isEmpty()) 227 sendMessage(Messages::NetworkSocketChannel::SendString { message }, byteLength); 228 else 229 m_pendingMessages.append(makeUnique<PendingMessage>(message)); 230 153 m_messageQueue.enqueue(message); 231 154 return SendSuccess; 232 155 } … … 237 160 return SendFail; 238 161 239 if (m_pendingMessages.isEmpty()) 240 sendMessage(Messages::NetworkSocketChannel::SendData { IPC::DataReference { static_cast<const uint8_t*>(binaryData.data()) + byteOffset, byteLength } }, byteLength); 241 else 242 m_pendingMessages.append(makeUnique<PendingMessage>(binaryData, byteOffset, byteLength)); 243 162 m_messageQueue.enqueue(binaryData, byteOffset, byteLength); 244 163 return SendSuccess; 245 164 } 246 165 247 WebSocketChannel::SendResult WebSocketChannel::send( WebCore::Blob& blob)248 { 249 // Avoid the Blob queue and loading for empty blobs.166 WebSocketChannel::SendResult WebSocketChannel::send(Blob& blob) 167 { 168 auto byteLength = blob.size(); 250 169 if (!blob.size()) 251 return send(JSC::ArrayBuffer::create(blob.size(), 1), 0, 0); 252 253 m_pendingMessages.append(makeUnique<PendingMessage>(m_document.get(), blob, [this] { 254 while (!m_pendingMessages.isEmpty()) { 255 auto& message = m_pendingMessages.first(); 256 257 switch (message->type()) { 258 case PendingMessage::Type::Text: 259 sendMessage(Messages::NetworkSocketChannel::SendString { message->textMessage() }, message->textMessage().sizeInBytes()); 260 break; 261 case PendingMessage::Type::Binary: { 262 const auto& binaryData = message->binaryData(); 263 sendMessage(Messages::NetworkSocketChannel::SendData { IPC::DataReference { reinterpret_cast<const uint8_t*>(binaryData.data()), binaryData.size() } }, binaryData.size()); 264 break; 265 } 266 case PendingMessage::Type::Blob: { 267 auto& loader = message->blobLoader(); 268 if (loader.isLoading()) 269 return; 270 271 if (const auto& result = loader.result()) { 272 auto byteLength = result->byteLength(); 273 if (increaseBufferedAmount(byteLength)) 274 sendMessage(Messages::NetworkSocketChannel::SendData { IPC::DataReference { reinterpret_cast<const uint8_t*>(result->data()), byteLength } }, byteLength); 275 } else if (auto errorCode = loader.errorCode()) 276 fail(makeString("Failed to load Blob: error code = ", errorCode.value())); 277 else 278 ASSERT_NOT_REACHED(); 279 break; 280 } 281 } 282 283 m_pendingMessages.removeFirst(); 284 } 285 })); 170 return send(JSC::ArrayBuffer::create(byteLength, 1), 0, 0); 171 172 if (!increaseBufferedAmount(byteLength)) 173 return SendFail; 174 175 m_messageQueue.enqueue(blob); 286 176 return SendSuccess; 287 177 } … … 317 207 m_document = nullptr; 318 208 m_pendingTasks.clear(); 319 m_ pendingMessages.clear();209 m_messageQueue.clear(); 320 210 321 211 MessageSender::send(Messages::NetworkSocketChannel::Close { 0, { } }); -
trunk/Source/WebKit/WebProcess/Network/WebSocketChannel.h
r248102 r249481 28 28 #include "MessageReceiver.h" 29 29 #include "MessageSender.h" 30 #include <WebCore/NetworkSendQueue.h> 30 31 #include <WebCore/ThreadableWebSocketChannel.h> 31 32 #include <pal/SessionID.h> 32 #include <wtf/Deque.h>33 33 #include <wtf/Identified.h> 34 34 #include <wtf/WeakPtr.h> … … 41 41 42 42 namespace WebKit { 43 44 class PendingMessage;45 43 46 44 class WebSocketChannel : public IPC::MessageSender, public IPC::MessageReceiver, public WebCore::ThreadableWebSocketChannel, public RefCounted<WebSocketChannel>, public Identified<WebSocketChannel> { … … 58 56 private: 59 57 WebSocketChannel(WebCore::Document&, WebCore::WebSocketChannelClient&); 58 59 static WebCore::NetworkSendQueue createMessageQueue(WebCore::Document&, WebSocketChannel&); 60 60 61 61 // ThreadableWebSocketChannel … … 99 99 bool m_isSuspended { false }; 100 100 Deque<Function<void()>> m_pendingTasks; 101 Deque<std::unique_ptr<PendingMessage>> m_pendingMessages;101 WebCore::NetworkSendQueue m_messageQueue; 102 102 }; 103 103
Note: See TracChangeset
for help on using the changeset viewer.