diff options
author | ericu@chromium.org <ericu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-29 09:57:07 +0000 |
---|---|---|
committer | ericu@chromium.org <ericu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-29 09:57:07 +0000 |
commit | 8e215a665c1591ce9230f9124398badd20a58a8c (patch) | |
tree | 6f88b10d1332a7c6335b5ecd1e815715151f0f37 | |
parent | e401d0348d7ed415a3cccc52768e4bb44c07f26a (diff) | |
download | chromium_src-8e215a665c1591ce9230f9124398badd20a58a8c.zip chromium_src-8e215a665c1591ce9230f9124398badd20a58a8c.tar.gz chromium_src-8e215a665c1591ce9230f9124398badd20a58a8c.tar.bz2 |
Allow BlobDataHandles to be copied, and have their UUIDs read, on any thread.
BUG=108012
Review URL: https://codereview.chromium.org/259773006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@266817 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | content/browser/fileapi/blob_storage_context_unittest.cc | 5 | ||||
-rw-r--r-- | webkit/browser/blob/blob_data_handle.cc | 66 | ||||
-rw-r--r-- | webkit/browser/blob/blob_data_handle.h | 35 | ||||
-rw-r--r-- | webkit/browser/blob/blob_storage_context.h | 2 |
4 files changed, 72 insertions, 36 deletions
diff --git a/content/browser/fileapi/blob_storage_context_unittest.cc b/content/browser/fileapi/blob_storage_context_unittest.cc index fd58880..05498b5 100644 --- a/content/browser/fileapi/blob_storage_context_unittest.cc +++ b/content/browser/fileapi/blob_storage_context_unittest.cc @@ -41,6 +41,7 @@ TEST(BlobStorageContextTest, IncrementDecrementRef) { blob_data_handle = context.GetBlobDataFromUUID(kId); EXPECT_TRUE(blob_data_handle); blob_data_handle.reset(); + fake_io_message_loop.RunUntilIdle(); // Make sure its still there after inc/dec. EXPECT_TRUE(host.IncrementBlobRefCount(kId)); @@ -48,6 +49,7 @@ TEST(BlobStorageContextTest, IncrementDecrementRef) { blob_data_handle = context.GetBlobDataFromUUID(kId); EXPECT_TRUE(blob_data_handle); blob_data_handle.reset(); + fake_io_message_loop.RunUntilIdle(); // Make sure it goes away in the end. EXPECT_TRUE(host.DecrementBlobRefCount(kId)); @@ -82,6 +84,7 @@ TEST(BlobStorageContextTest, BlobDataHandle) { // Should disappear after dropping both handles. blob_data_handle.reset(); another_handle.reset(); + fake_io_message_loop.RunUntilIdle(); blob_data_handle = context.GetBlobDataFromUUID(kId); EXPECT_FALSE(blob_data_handle); } @@ -150,6 +153,7 @@ TEST(BlobStorageContextTest, PublicBlobUrls) { ASSERT_TRUE(blob_data_handle.get()); EXPECT_EQ(kId, blob_data_handle->data()->uuid()); blob_data_handle.reset(); + fake_io_message_loop.RunUntilIdle(); // The url registration should keep the blob alive even after // explicit references are dropped. @@ -157,6 +161,7 @@ TEST(BlobStorageContextTest, PublicBlobUrls) { blob_data_handle = context.GetBlobDataFromPublicURL(kUrl); EXPECT_TRUE(blob_data_handle); blob_data_handle.reset(); + fake_io_message_loop.RunUntilIdle(); // Finally get rid of the url registration and the blob. EXPECT_TRUE(host.RevokePublicBlobURL(kUrl)); diff --git a/webkit/browser/blob/blob_data_handle.cc b/webkit/browser/blob/blob_data_handle.cc index fd0ae54..8ccba74 100644 --- a/webkit/browser/blob/blob_data_handle.cc +++ b/webkit/browser/blob/blob_data_handle.cc @@ -13,44 +13,56 @@ namespace webkit_blob { -BlobDataHandle::BlobDataHandle(BlobData* blob_data, BlobStorageContext* context, - base::SequencedTaskRunner* task_runner) +BlobDataHandle::BlobDataHandleShared::BlobDataHandleShared( + BlobData* blob_data, + BlobStorageContext* context, + base::SequencedTaskRunner* task_runner) : blob_data_(blob_data), - context_(context->AsWeakPtr()), - io_task_runner_(task_runner) { - // Ensures the uuid remains registered and the underlying data is not deleted. - DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); + context_(context->AsWeakPtr()) { context_->IncrementBlobRefCount(blob_data->uuid()); - blob_data_->AddRef(); } -BlobDataHandle::~BlobDataHandle() { - if (io_task_runner_->RunsTasksOnCurrentThread()) { - // Note: Do not test context_ or alter the blob_data_ refcount - // on the wrong thread. - if (context_.get()) - context_->DecrementBlobRefCount(blob_data_->uuid()); - blob_data_->Release(); - return; - } +BlobData* BlobDataHandle::BlobDataHandleShared::data() const { + return blob_data_; +} - io_task_runner_->PostTask( - FROM_HERE, - base::Bind(&DeleteHelper, context_, base::Unretained(blob_data_))); +const std::string& BlobDataHandle::BlobDataHandleShared::uuid() const { + return blob_data_->uuid(); +} + +BlobDataHandle::BlobDataHandleShared::~BlobDataHandleShared() { + if (context_.get()) + context_->DecrementBlobRefCount(blob_data_->uuid()); +} + +BlobDataHandle::BlobDataHandle(BlobData* blob_data, + BlobStorageContext* context, + base::SequencedTaskRunner* task_runner) + : io_task_runner_(task_runner), + shared_(new BlobDataHandleShared(blob_data, context, task_runner)) { + DCHECK(io_task_runner_); + DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); +} + +BlobDataHandle::BlobDataHandle(const BlobDataHandle& other) { + io_task_runner_ = other.io_task_runner_; + shared_ = other.shared_; +} + +BlobDataHandle::~BlobDataHandle() { + BlobDataHandleShared* raw = shared_.get(); + raw->AddRef(); + shared_ = 0; + io_task_runner_->ReleaseSoon(FROM_HERE, raw); } BlobData* BlobDataHandle::data() const { DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); - return blob_data_; + return shared_->data(); } -// static -void BlobDataHandle::DeleteHelper( - base::WeakPtr<BlobStorageContext> context, - BlobData* blob_data) { - if (context.get()) - context->DecrementBlobRefCount(blob_data->uuid()); - blob_data->Release(); +std::string BlobDataHandle::uuid() const { + return shared_->uuid(); } } // namespace webkit_blob diff --git a/webkit/browser/blob/blob_data_handle.h b/webkit/browser/blob/blob_data_handle.h index 5f870f2..917a0b3 100644 --- a/webkit/browser/blob/blob_data_handle.h +++ b/webkit/browser/blob/blob_data_handle.h @@ -28,23 +28,42 @@ class BlobStorageContext; class WEBKIT_STORAGE_BROWSER_EXPORT BlobDataHandle : public base::SupportsUserData::Data { public: + BlobDataHandle(const BlobDataHandle& other); // May be copied on any thread. virtual ~BlobDataHandle(); // Maybe be deleted on any thread. BlobData* data() const; // May only be accessed on the IO thread. + std::string uuid() const; // May be accessed on any thread. + private: + class BlobDataHandleShared + : public base::RefCountedThreadSafe<BlobDataHandleShared> { + public: + BlobDataHandleShared(BlobData* blob_data, + BlobStorageContext* context, + base::SequencedTaskRunner* task_runner); + + BlobData* data() const; + const std::string& uuid() const; + + private: + friend class base::DeleteHelper<BlobDataHandleShared>; + friend class base::RefCountedThreadSafe<BlobDataHandleShared>; + friend class BlobDataHandle; + + virtual ~BlobDataHandleShared(); + + scoped_refptr<BlobData> blob_data_; + base::WeakPtr<BlobStorageContext> context_; + + DISALLOW_COPY_AND_ASSIGN(BlobDataHandleShared); + }; + friend class BlobStorageContext; BlobDataHandle(BlobData* blob_data, BlobStorageContext* context, base::SequencedTaskRunner* task_runner); - static void DeleteHelper( - base::WeakPtr<BlobStorageContext> context, - BlobData* blob_data); - - BlobData* blob_data_; // Intentionally a raw ptr to a non-thread-safe ref. - base::WeakPtr<BlobStorageContext> context_; scoped_refptr<base::SequencedTaskRunner> io_task_runner_; - - DISALLOW_COPY_AND_ASSIGN(BlobDataHandle); + scoped_refptr<BlobDataHandleShared> shared_; }; } // namespace webkit_blob diff --git a/webkit/browser/blob/blob_storage_context.h b/webkit/browser/blob/blob_storage_context.h index dda669a..a753c59 100644 --- a/webkit/browser/blob/blob_storage_context.h +++ b/webkit/browser/blob/blob_storage_context.h @@ -53,7 +53,7 @@ class WEBKIT_STORAGE_BROWSER_EXPORT BlobStorageContext private: friend class content::BlobStorageHost; - friend class BlobDataHandle; + friend class BlobDataHandle::BlobDataHandleShared; friend class ViewBlobInternalsJob; enum EntryFlags { |