1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "third_party/blink/renderer/modules/cache_storage/cache_storage_blob_client_list.h"
6
7 namespace blink {
8
9 // Class implementing the BlobReaderClient interface. This is used to
10 // propagate the completion of an eager body blob read to the
11 // DataPipeBytesConsumer.
12 class CacheStorageBlobClientList::Client
13 : public GarbageCollected<CacheStorageBlobClientList::Client>,
14 public mojom::blink::BlobReaderClient {
15 // We must prevent any mojo messages from coming in after this object
16 // starts getting garbage collected.
17 USING_PRE_FINALIZER(CacheStorageBlobClientList::Client, Dispose);
18
19 public:
Client(CacheStorageBlobClientList * owner,mojo::PendingReceiver<mojom::blink::BlobReaderClient> client_pending_receiver,DataPipeBytesConsumer::CompletionNotifier * completion_notifier)20 Client(CacheStorageBlobClientList* owner,
21 mojo::PendingReceiver<mojom::blink::BlobReaderClient>
22 client_pending_receiver,
23 DataPipeBytesConsumer::CompletionNotifier* completion_notifier)
24 : owner_(owner),
25 client_receiver_(this, std::move(client_pending_receiver)),
26 completion_notifier_(completion_notifier) {}
27
OnCalculatedSize(uint64_t total_size,uint64_t expected_content_size)28 void OnCalculatedSize(uint64_t total_size,
29 uint64_t expected_content_size) override {}
30
OnComplete(int32_t status,uint64_t data_length)31 void OnComplete(int32_t status, uint64_t data_length) override {
32 client_receiver_.reset();
33
34 // 0 is net::OK
35 if (status == 0)
36 completion_notifier_->SignalComplete();
37 else
38 completion_notifier_->SignalError(BytesConsumer::Error());
39
40 if (owner_)
41 owner_->RevokeClient(this);
42 }
43
Trace(Visitor * visitor)44 void Trace(Visitor* visitor) {
45 visitor->Trace(owner_);
46 visitor->Trace(completion_notifier_);
47 }
48
49 private:
Dispose()50 void Dispose() {
51 // Use the existence of the client_receiver_ binding to see if this
52 // client has already completed.
53 if (!client_receiver_.is_bound())
54 return;
55
56 client_receiver_.reset();
57 completion_notifier_->SignalError(BytesConsumer::Error("aborted"));
58
59 // If we are already being garbage collected its not necessary to
60 // call RevokeClient() on the owner.
61 }
62
63 WeakMember<CacheStorageBlobClientList> owner_;
64 mojo::Receiver<mojom::blink::BlobReaderClient> client_receiver_;
65 Member<DataPipeBytesConsumer::CompletionNotifier> completion_notifier_;
66
67 DISALLOW_COPY_AND_ASSIGN(Client);
68 };
69
AddClient(mojo::PendingReceiver<mojom::blink::BlobReaderClient> client_pending_receiver,DataPipeBytesConsumer::CompletionNotifier * completion_notifier)70 void CacheStorageBlobClientList::AddClient(
71 mojo::PendingReceiver<mojom::blink::BlobReaderClient>
72 client_pending_receiver,
73 DataPipeBytesConsumer::CompletionNotifier* completion_notifier) {
74 clients.emplace_back(MakeGarbageCollected<Client>(
75 this, std::move(client_pending_receiver), completion_notifier));
76 }
77
Trace(Visitor * visitor)78 void CacheStorageBlobClientList::Trace(Visitor* visitor) {
79 visitor->Trace(clients);
80 }
81
RevokeClient(Client * client)82 void CacheStorageBlobClientList::RevokeClient(Client* client) {
83 auto index = clients.Find(client);
84 clients.EraseAt(index);
85 }
86
87 } // namespace blink
88