Skip to content

Commit

Permalink
Use WeakPtr for BlobStorageContext in BlobRegistryImpl.
Browse files Browse the repository at this point in the history
Since BlobStorageContext and BlobRegistryImpl are owned by different
classes it is possible for BlobRegistryImpl to outlive
BlobStorageContext. So rather than keeping a raw pointer to the context,
change that to a weak pointer, and guard every access to it with a null
check.

Bug: 779495
Change-Id: Ie35bc4135c4839cfd4c3e3836f83669349e7401a
Reviewed-on: https://chromium-review.googlesource.com/748912
Commit-Queue: Daniel Murphy <dmurph@chromium.org>
Reviewed-by: Daniel Murphy <dmurph@chromium.org>
Cr-Commit-Position: refs/heads/master@{#513216}
  • Loading branch information
mkruisselbrink authored and Commit Bot committed Nov 1, 2017
1 parent f659447 commit 073fff4
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 12 deletions.
4 changes: 3 additions & 1 deletion content/browser/blob_storage/blob_registry_wrapper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "content/browser/child_process_security_policy_impl.h"
#include "content/public/common/content_features.h"
#include "storage/browser/blob/blob_registry_impl.h"
#include "storage/browser/blob/blob_storage_context.h"
#include "storage/browser/fileapi/file_system_context.h"

namespace content {
Expand Down Expand Up @@ -72,7 +73,8 @@ void BlobRegistryWrapper::InitializeOnIOThread(
scoped_refptr<storage::FileSystemContext> file_system_context) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
blob_registry_ = std::make_unique<storage::BlobRegistryImpl>(
blob_storage_context->context(), std::move(file_system_context));
blob_storage_context->context()->AsWeakPtr(),
std::move(file_system_context));
}

} // namespace content
46 changes: 38 additions & 8 deletions storage/browser/blob/blob_registry_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class BlobURLHandleImpl final : public blink::mojom::BlobURLHandle {
const GURL& url) {
blink::mojom::BlobURLHandlePtr ptr;
mojo::MakeStrongBinding(
base::WrapUnique(new BlobURLHandleImpl(context, url)),
base::WrapUnique(new BlobURLHandleImpl(std::move(context), url)),
mojo::MakeRequest(&ptr));
return ptr;
}
Expand Down Expand Up @@ -103,7 +103,7 @@ class BlobRegistryImpl::BlobUnderConstruction {
const std::string& uuid() const { return builder_.uuid(); }

private:
BlobStorageContext* context() const { return blob_registry_->context_; }
BlobStorageContext* context() const { return blob_registry_->context_.get(); }

// Marks this blob as broken. If an optional |bad_message_reason| is provided,
// this will also report a BadMessage on the binding over which the initial
Expand All @@ -115,7 +115,7 @@ class BlobRegistryImpl::BlobUnderConstruction {
DCHECK_EQ(bad_message_reason.empty(), !BlobStatusIsBadIPC(reason));
// The blob might no longer have any references, in which case it may no
// longer exist. If that happens just skip calling cancel.
if (context()->registry().HasEntry(uuid()))
if (context() && context()->registry().HasEntry(uuid()))
context()->CancelBuildingBlob(uuid(), reason);
if (!bad_message_reason.empty())
std::move(bad_message_callback_).Run(bad_message_reason);
Expand Down Expand Up @@ -199,6 +199,11 @@ class BlobRegistryImpl::BlobUnderConstruction {
};

void BlobRegistryImpl::BlobUnderConstruction::StartTransportation() {
if (!context()) {
MarkAsFinishedAndDeleteSelf();
return;
}

size_t blob_count = 0;
for (size_t i = 0; i < elements_.size(); ++i) {
const auto& element = elements_[i];
Expand Down Expand Up @@ -282,6 +287,11 @@ void BlobRegistryImpl::BlobUnderConstruction::ResolvedAllBlobUUIDs() {
}
#endif

if (!context()) {
MarkAsFinishedAndDeleteSelf();
return;
}

if (referenced_blob_uuids_.size() == 0) {
ResolvedAllBlobDependencies();
return;
Expand Down Expand Up @@ -321,6 +331,11 @@ void BlobRegistryImpl::BlobUnderConstruction::ResolvedAllBlobDependencies() {
DCHECK_EQ(resolved_blob_uuid_count_, referenced_blob_uuids_.size());
DCHECK_EQ(ready_dependent_blob_count_, referenced_blob_uuids_.size());

if (!context()) {
MarkAsFinishedAndDeleteSelf();
return;
}

auto blob_uuid_it = referenced_blob_uuids_.begin();
for (const auto& element : elements_) {
if (element->is_bytes()) {
Expand Down Expand Up @@ -378,6 +393,11 @@ void BlobRegistryImpl::BlobUnderConstruction::OnReadyForTransport(

void BlobRegistryImpl::BlobUnderConstruction::TransportComplete(
BlobStatus result) {
if (!context()) {
MarkAsFinishedAndDeleteSelf();
return;
}

// The blob might no longer have any references, in which case it may no
// longer exist. If that happens just skip calling Complete.
// TODO(mek): Stop building sooner if a blob is no longer referenced.
Expand Down Expand Up @@ -417,9 +437,9 @@ bool BlobRegistryImpl::BlobUnderConstruction::ContainsCycles(
#endif

BlobRegistryImpl::BlobRegistryImpl(
BlobStorageContext* context,
base::WeakPtr<BlobStorageContext> context,
scoped_refptr<FileSystemContext> file_system_context)
: context_(context),
: context_(std::move(context)),
file_system_context_(std::move(file_system_context)),
weak_ptr_factory_(this) {}

Expand All @@ -438,6 +458,11 @@ void BlobRegistryImpl::Register(
const std::string& content_disposition,
std::vector<blink::mojom::DataElementPtr> elements,
RegisterCallback callback) {
if (!context_) {
std::move(callback).Run();
return;
}

if (uuid.empty() || context_->registry().HasEntry(uuid) ||
base::ContainsKey(blobs_under_construction_, uuid)) {
bindings_.ReportBadMessage("Invalid UUID passed to BlobRegistry::Register");
Expand Down Expand Up @@ -496,6 +521,11 @@ void BlobRegistryImpl::Register(
void BlobRegistryImpl::GetBlobFromUUID(blink::mojom::BlobRequest blob,
const std::string& uuid,
GetBlobFromUUIDCallback callback) {
if (!context_) {
std::move(callback).Run();
return;
}

if (uuid.empty()) {
bindings_.ReportBadMessage(
"Invalid UUID passed to BlobRegistry::GetBlobFromUUID");
Expand Down Expand Up @@ -533,9 +563,9 @@ void BlobRegistryImpl::RegisterURLWithUUID(const GURL& url,
const std::string& uuid) {
// |blob| is unused, but is passed here to be kept alive until
// RegisterBlobURL increments the refcount of it via the uuid.
context_->RegisterPublicBlobURL(url, uuid);
std::move(callback).Run(
BlobURLHandleImpl::Create(context_->AsWeakPtr(), url));
if (context_)
context_->RegisterPublicBlobURL(url, uuid);
std::move(callback).Run(BlobURLHandleImpl::Create(context_, url));
}

} // namespace storage
4 changes: 2 additions & 2 deletions storage/browser/blob/blob_registry_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class STORAGE_EXPORT BlobRegistryImpl : public blink::mojom::BlobRegistry {
virtual bool CanCommitURL(const GURL& url) = 0;
};

BlobRegistryImpl(BlobStorageContext* context,
BlobRegistryImpl(base::WeakPtr<BlobStorageContext> context,
scoped_refptr<FileSystemContext> file_system_context);
~BlobRegistryImpl() override;

Expand Down Expand Up @@ -61,7 +61,7 @@ class STORAGE_EXPORT BlobRegistryImpl : public blink::mojom::BlobRegistry {

class BlobUnderConstruction;

BlobStorageContext* context_;
base::WeakPtr<BlobStorageContext> context_;
scoped_refptr<FileSystemContext> file_system_context_;

mojo::BindingSet<blink::mojom::BlobRegistry, std::unique_ptr<Delegate>>
Expand Down
2 changes: 1 addition & 1 deletion storage/browser/blob/blob_registry_impl_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ class BlobRegistryImplTest : public testing::Test {
std::vector<URLRequestAutoMountHandler>(), data_dir_.GetPath(),
FileSystemOptions(FileSystemOptions::PROFILE_MODE_INCOGNITO,
std::vector<std::string>(), nullptr));
registry_impl_ = base::MakeUnique<BlobRegistryImpl>(context_.get(),
registry_impl_ = base::MakeUnique<BlobRegistryImpl>(context_->AsWeakPtr(),
file_system_context_);
auto delegate = base::MakeUnique<MockDelegate>();
delegate_ptr_ = delegate.get();
Expand Down

0 comments on commit 073fff4

Please sign in to comment.