Commit 90d4dbbb authored by Lei Zhang's avatar Lei Zhang Committed by Commit Bot

Implement base::RefCountedSharedMemory.

This base::RefCountedMemory subclass owns a base::SharedMemory instance.
Use this class to easily access data in shared memory via the
base::RefCountedMemory interface without having to copy it out to a
std::string or std::vector.

Use this in printing code to avoid a bunch of copying.

Change-Id: I275eacb3af0250d352ec909429d8563b28b1b57e
Reviewed-on: https://chromium-review.googlesource.com/978641
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: default avatarWei Li <weili@chromium.org>
Reviewed-by: default avatarRebekah Potter <rbpotter@chromium.org>
Reviewed-by: default avatarReilly Grant <reillyg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#547048}
parent 27176aa4
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include "base/memory/ref_counted_memory.h" #include "base/memory/ref_counted_memory.h"
#include <utility>
#include "base/logging.h" #include "base/logging.h"
namespace base { namespace base {
...@@ -80,4 +82,24 @@ size_t RefCountedString::size() const { ...@@ -80,4 +82,24 @@ size_t RefCountedString::size() const {
return data_.size(); return data_.size();
} }
RefCountedSharedMemory::RefCountedSharedMemory(
std::unique_ptr<SharedMemory> shm,
size_t size)
: shm_(std::move(shm)), size_(size) {
DCHECK(shm_);
DCHECK(shm_->memory());
DCHECK_GT(size_, 0U);
DCHECK_LE(size_, shm_->mapped_size());
}
RefCountedSharedMemory::~RefCountedSharedMemory() = default;
const unsigned char* RefCountedSharedMemory::front() const {
return reinterpret_cast<const unsigned char*>(shm_->memory());
}
size_t RefCountedSharedMemory::size() const {
return size_;
}
} // namespace base } // namespace base
...@@ -7,12 +7,14 @@ ...@@ -7,12 +7,14 @@
#include <stddef.h> #include <stddef.h>
#include <memory>
#include <string> #include <string>
#include <vector> #include <vector>
#include "base/base_export.h" #include "base/base_export.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/memory/shared_memory.h"
namespace base { namespace base {
...@@ -136,6 +138,27 @@ class BASE_EXPORT RefCountedString : public RefCountedMemory { ...@@ -136,6 +138,27 @@ class BASE_EXPORT RefCountedString : public RefCountedMemory {
DISALLOW_COPY_AND_ASSIGN(RefCountedString); DISALLOW_COPY_AND_ASSIGN(RefCountedString);
}; };
// An implementation of RefCountedMemory, where the bytes are stored in shared
// memory.
class BASE_EXPORT RefCountedSharedMemory : public RefCountedMemory {
public:
// Constructs a RefCountedMemory object by taking ownership of an already
// mapped SharedMemory object.
RefCountedSharedMemory(std::unique_ptr<SharedMemory> shm, size_t size);
// RefCountedMemory:
const unsigned char* front() const override;
size_t size() const override;
private:
~RefCountedSharedMemory() override;
const std::unique_ptr<SharedMemory> shm_;
const size_t size_;
DISALLOW_COPY_AND_ASSIGN(RefCountedSharedMemory);
};
} // namespace base } // namespace base
#endif // BASE_MEMORY_REF_COUNTED_MEMORY_H_ #endif // BASE_MEMORY_REF_COUNTED_MEMORY_H_
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
#include <stdint.h> #include <stdint.h>
#include <utility>
#include "testing/gmock/include/gmock/gmock.h" #include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
...@@ -70,6 +72,20 @@ TEST(RefCountedMemoryUnitTest, RefCountedString) { ...@@ -70,6 +72,20 @@ TEST(RefCountedMemoryUnitTest, RefCountedString) {
EXPECT_EQ('e', mem->front()[9]); EXPECT_EQ('e', mem->front()[9]);
} }
TEST(RefCountedMemoryUnitTest, RefCountedSharedMemory) {
static const char kData[] = "shm_dummy_data";
auto shm = std::make_unique<SharedMemory>();
ASSERT_TRUE(shm->CreateAndMapAnonymous(sizeof(kData)));
memcpy(shm->memory(), kData, sizeof(kData));
auto mem =
MakeRefCounted<RefCountedSharedMemory>(std::move(shm), sizeof(kData));
ASSERT_EQ(sizeof(kData), mem->size());
EXPECT_EQ('s', mem->front()[0]);
EXPECT_EQ('h', mem->front()[1]);
EXPECT_EQ('_', mem->front()[9]);
}
TEST(RefCountedMemoryUnitTest, Equals) { TEST(RefCountedMemoryUnitTest, Equals) {
std::string s1("same"); std::string s1("same");
scoped_refptr<RefCountedMemory> mem1 = RefCountedString::TakeString(&s1); scoped_refptr<RefCountedMemory> mem1 = RefCountedString::TakeString(&s1);
......
...@@ -67,9 +67,8 @@ scoped_refptr<base::RefCountedMemory> GetDataFromHandle( ...@@ -67,9 +67,8 @@ scoped_refptr<base::RefCountedMemory> GetDataFromHandle(
return nullptr; return nullptr;
} }
unsigned char* data_begin = static_cast<unsigned char*>(shared_buf->memory()); return base::MakeRefCounted<base::RefCountedSharedMemory>(
std::vector<unsigned char> data(data_begin, data_begin + data_size); std::move(shared_buf), data_size);
return base::RefCountedBytes::TakeVector(&data);
} }
} // namespace } // namespace
......
...@@ -334,11 +334,13 @@ void PrintViewManagerBase::OnComposePdfDone( ...@@ -334,11 +334,13 @@ void PrintViewManagerBase::OnComposePdfDone(
std::unique_ptr<base::SharedMemory> shared_buf = std::unique_ptr<base::SharedMemory> shared_buf =
GetShmFromMojoHandle(std::move(handle)); GetShmFromMojoHandle(std::move(handle));
scoped_refptr<base::RefCountedBytes> bytes = if (!shared_buf)
base::MakeRefCounted<base::RefCountedBytes>( return;
reinterpret_cast<const unsigned char*>(shared_buf->memory()),
shared_buf->mapped_size()); size_t size = shared_buf->mapped_size();
PrintDocument(document, bytes, params.page_size, params.content_area, auto data = base::MakeRefCounted<base::RefCountedSharedMemory>(
std::move(shared_buf), size);
PrintDocument(document, data, params.page_size, params.content_area,
params.physical_offsets); params.physical_offsets);
} }
...@@ -372,11 +374,10 @@ void PrintViewManagerBase::OnDidPrintDocument( ...@@ -372,11 +374,10 @@ void PrintViewManagerBase::OnDidPrintDocument(
web_contents()->Stop(); web_contents()->Stop();
return; return;
} }
scoped_refptr<base::RefCountedBytes> bytes =
base::MakeRefCounted<base::RefCountedBytes>( auto data = base::MakeRefCounted<base::RefCountedSharedMemory>(
reinterpret_cast<const unsigned char*>(shared_buf->memory()), std::move(shared_buf), content.data_size);
content.data_size); PrintDocument(document, data, params.page_size, params.content_area,
PrintDocument(document, bytes, params.page_size, params.content_area,
params.physical_offsets); params.physical_offsets);
} }
......
...@@ -42,9 +42,9 @@ scoped_refptr<base::RefCountedMemory> GetDataFromMojoHandle( ...@@ -42,9 +42,9 @@ scoped_refptr<base::RefCountedMemory> GetDataFromMojoHandle(
if (!shm) if (!shm)
return nullptr; return nullptr;
return base::MakeRefCounted<base::RefCountedBytes>( size_t size = shm->mapped_size();
reinterpret_cast<const unsigned char*>(shm->memory()), return base::MakeRefCounted<base::RefCountedSharedMemory>(std::move(shm),
shm->mapped_size()); size);
} }
} // namespace printing } // namespace printing
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment