blob: 36d39a9bce300e7bf0779f8ecc20a396170d14e7 [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/modules/cache_storage/cache_storage_blob_client_list.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/platform/mojo/heap_mojo_receiver.h"
namespace blink {
// Class implementing the BlobReaderClient interface. This is used to
// propagate the completion of an eager body blob read to the
// DataPipeBytesConsumer.
class CacheStorageBlobClientList::Client
: public GarbageCollected<CacheStorageBlobClientList::Client>,
public mojom::blink::BlobReaderClient {
// We must prevent any mojo messages from coming in after this object
// starts getting garbage collected.
USING_PRE_FINALIZER(CacheStorageBlobClientList::Client, Dispose);
public:
Client(CacheStorageBlobClientList* owner,
ExecutionContext* context,
mojo::PendingReceiver<mojom::blink::BlobReaderClient>
client_pending_receiver,
DataPipeBytesConsumer::CompletionNotifier* completion_notifier)
: owner_(owner),
client_receiver_(this, context),
completion_notifier_(completion_notifier) {
client_receiver_.Bind(std::move(client_pending_receiver),
context->GetTaskRunner(TaskType::kMiscPlatformAPI));
}
void OnCalculatedSize(uint64_t total_size,
uint64_t expected_content_size) override {}
void OnComplete(int32_t status, uint64_t data_length) override {
client_receiver_.reset();
// 0 is net::OK
if (status == 0)
completion_notifier_->SignalComplete();
else
completion_notifier_->SignalError(BytesConsumer::Error());
if (owner_)
owner_->RevokeClient(this);
}
void Trace(Visitor* visitor) const {
visitor->Trace(owner_);
visitor->Trace(completion_notifier_);
visitor->Trace(client_receiver_);
}
private:
void Dispose() {
// Use the existence of the client_receiver_ binding to see if this
// client has already completed.
if (!client_receiver_.is_bound())
return;
client_receiver_.reset();
completion_notifier_->SignalError(BytesConsumer::Error("aborted"));
// If we are already being garbage collected its not necessary to
// call RevokeClient() on the owner.
}
WeakMember<CacheStorageBlobClientList> owner_;
HeapMojoReceiver<mojom::blink::BlobReaderClient, Client> client_receiver_;
Member<DataPipeBytesConsumer::CompletionNotifier> completion_notifier_;
DISALLOW_COPY_AND_ASSIGN(Client);
};
void CacheStorageBlobClientList::AddClient(
ExecutionContext* context,
mojo::PendingReceiver<mojom::blink::BlobReaderClient>
client_pending_receiver,
DataPipeBytesConsumer::CompletionNotifier* completion_notifier) {
clients_.emplace_back(MakeGarbageCollected<Client>(
this, context, std::move(client_pending_receiver), completion_notifier));
}
void CacheStorageBlobClientList::Trace(Visitor* visitor) const {
visitor->Trace(clients_);
}
void CacheStorageBlobClientList::RevokeClient(Client* client) {
auto index = clients_.Find(client);
clients_.EraseAt(index);
}
} // namespace blink