| Index: content/common/font_config_ipc_linux.cc
|
| diff --git a/content/common/font_config_ipc_linux.cc b/content/common/font_config_ipc_linux.cc
|
| index da8246d818c30bf6935afac90f42acd3d46b6e49..540d7d88825c61d660eda9c2591b2adeb6b51054 100644
|
| --- a/content/common/font_config_ipc_linux.cc
|
| +++ b/content/common/font_config_ipc_linux.cc
|
| @@ -13,8 +13,11 @@
|
| #include <unistd.h>
|
|
|
| #include "base/files/file_util.h"
|
| +#include "base/files/memory_mapped_file.h"
|
| +#include "base/memory/ref_counted.h"
|
| #include "base/pickle.h"
|
| #include "base/posix/unix_domain_socket_linux.h"
|
| +#include "base/threading/thread_restrictions.h"
|
| #include "base/trace_event/trace_event.h"
|
| #include "skia/ext/refptr.h"
|
| #include "skia/ext/skia_utils_base.h"
|
| @@ -24,14 +27,45 @@
|
|
|
| namespace content {
|
|
|
| -// Return a stream from the file descriptor, or NULL on failure.
|
| -SkStreamAsset* StreamFromFD(int fd) {
|
| - skia::RefPtr<SkData> data = skia::AdoptRef(SkData::NewFromFD(fd));
|
| - if (!data) {
|
| - return NULL;
|
| +class FontConfigIPC::MappedFontFile
|
| + : public base::RefCountedThreadSafe<MappedFontFile> {
|
| + public:
|
| + explicit MappedFontFile(uint32_t font_id) : font_id_(font_id) {}
|
| +
|
| + uint32_t font_id() const { return font_id_; }
|
| +
|
| + bool Initialize(int fd) {
|
| + base::ThreadRestrictions::ScopedAllowIO allow_mmap;
|
| + return mapped_font_file_.Initialize(base::File(fd));
|
| + }
|
| +
|
| + SkMemoryStream* CreateMemoryStream() {
|
| + DCHECK(mapped_font_file_.IsValid());
|
| + auto data = skia::AdoptRef(SkData::NewWithProc(
|
| + mapped_font_file_.data(), mapped_font_file_.length(),
|
| + &MappedFontFile::ReleaseProc, this));
|
| + if (!data)
|
| + return nullptr;
|
| + AddRef();
|
| + return new SkMemoryStream(data.get());
|
| + }
|
| +
|
| + private:
|
| + friend class base::RefCountedThreadSafe<MappedFontFile>;
|
| +
|
| + ~MappedFontFile() {
|
| + auto font_config = static_cast<FontConfigIPC*>(FontConfigIPC::RefGlobal());
|
| + font_config->RemoveMappedFontFile(this);
|
| }
|
| - return new SkMemoryStream(data.get());
|
| -}
|
| +
|
| + static void ReleaseProc(const void* ptr, size_t length, void* context) {
|
| + base::ThreadRestrictions::ScopedAllowIO allow_munmap;
|
| + static_cast<MappedFontFile*>(context)->Release();
|
| + }
|
| +
|
| + uint32_t font_id_;
|
| + base::MemoryMappedFile mapped_font_file_;
|
| +};
|
|
|
| void CloseFD(int fd) {
|
| int err = IGNORE_EINTR(close(fd));
|
| @@ -97,6 +131,14 @@ bool FontConfigIPC::matchFamilyName(const char familyName[],
|
|
|
| SkStreamAsset* FontConfigIPC::openStream(const FontIdentity& identity) {
|
| TRACE_EVENT0("sandbox_ipc", "FontConfigIPC::openStream");
|
| +
|
| + {
|
| + base::AutoLock lock(lock_);
|
| + auto mapped_font_files_it = mapped_font_files_.find(identity.fID);
|
| + if (mapped_font_files_it != mapped_font_files_.end())
|
| + return mapped_font_files_it->second->CreateMemoryStream();
|
| + }
|
| +
|
| Pickle request;
|
| request.WriteInt(METHOD_OPEN);
|
| request.WriteUInt32(identity.fID);
|
| @@ -119,9 +161,23 @@ SkStreamAsset* FontConfigIPC::openStream(const FontIdentity& identity) {
|
| return NULL;
|
| }
|
|
|
| - SkStreamAsset* stream = StreamFromFD(result_fd);
|
| - CloseFD(result_fd);
|
| - return stream;
|
| + scoped_refptr<MappedFontFile> mapped_font_file =
|
| + new MappedFontFile(identity.fID);
|
| + if (!mapped_font_file->Initialize(result_fd))
|
| + return nullptr;
|
| +
|
| + {
|
| + base::AutoLock lock(lock_);
|
| + auto mapped_font_files_it =
|
| + mapped_font_files_.insert(std::make_pair(mapped_font_file->font_id(),
|
| + mapped_font_file.get())).first;
|
| + return mapped_font_files_it->second->CreateMemoryStream();
|
| + }
|
| +}
|
| +
|
| +void FontConfigIPC::RemoveMappedFontFile(MappedFontFile* mapped_font_file) {
|
| + base::AutoLock lock(lock_);
|
| + mapped_font_files_.erase(mapped_font_file->font_id());
|
| }
|
|
|
| } // namespace content
|
|
|