diff options
Diffstat (limited to 'chromium/content/common/font_config_ipc_linux.cc')
-rw-r--r-- | chromium/content/common/font_config_ipc_linux.cc | 92 |
1 files changed, 74 insertions, 18 deletions
diff --git a/chromium/content/common/font_config_ipc_linux.cc b/chromium/content/common/font_config_ipc_linux.cc index fcb06ebac0d..540d7d88825 100644 --- a/chromium/content/common/font_config_ipc_linux.cc +++ b/chromium/content/common/font_config_ipc_linux.cc @@ -12,25 +12,60 @@ #include <sys/uio.h> #include <unistd.h> -#include "base/debug/trace_event.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" #include "third_party/skia/include/core/SkData.h" #include "third_party/skia/include/core/SkStream.h" +#include "third_party/skia/include/core/SkTypeface.h" namespace content { -// Return a stream from the file descriptor, or NULL on failure. -SkStream* 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)); @@ -70,7 +105,7 @@ bool FontConfigIPC::matchFamilyName(const char familyName[], Pickle reply(reinterpret_cast<char*>(reply_buf), r); PickleIterator iter(reply); bool result; - if (!reply.ReadBool(&iter, &result)) + if (!iter.ReadBool(&result)) return false; if (!result) return false; @@ -78,9 +113,9 @@ bool FontConfigIPC::matchFamilyName(const char familyName[], SkString reply_family; FontIdentity reply_identity; uint32_t reply_style; - if (!skia::ReadSkString(reply, &iter, &reply_family) || - !skia::ReadSkFontIdentity(reply, &iter, &reply_identity) || - !reply.ReadUInt32(&iter, &reply_style)) { + if (!skia::ReadSkString(&iter, &reply_family) || + !skia::ReadSkFontIdentity(&iter, &reply_identity) || + !iter.ReadUInt32(&reply_style)) { return false; } @@ -94,8 +129,16 @@ bool FontConfigIPC::matchFamilyName(const char familyName[], return true; } -SkStream* FontConfigIPC::openStream(const FontIdentity& identity) { +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); @@ -112,16 +155,29 @@ SkStream* FontConfigIPC::openStream(const FontIdentity& identity) { Pickle reply(reinterpret_cast<char*>(reply_buf), r); bool result; PickleIterator iter(reply); - if (!reply.ReadBool(&iter, &result) || - !result) { + if (!iter.ReadBool(&result) || !result) { if (result_fd) CloseFD(result_fd); return NULL; } - SkStream* 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 |