Index: chrome/browser/nacl_host/pnacl_translation_cache.cc |
diff --git a/chrome/browser/nacl_host/pnacl_translation_cache.cc b/chrome/browser/nacl_host/pnacl_translation_cache.cc |
deleted file mode 100644 |
index 56354792ebb6bf4ffe854927401c8781a44ceac4..0000000000000000000000000000000000000000 |
--- a/chrome/browser/nacl_host/pnacl_translation_cache.cc |
+++ /dev/null |
@@ -1,440 +0,0 @@ |
-// Copyright 2013 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "chrome/browser/nacl_host/pnacl_translation_cache.h" |
- |
-#include <string> |
- |
-#include "base/callback.h" |
-#include "base/files/file_path.h" |
-#include "base/logging.h" |
-#include "base/strings/string_number_conversions.h" |
-#include "base/threading/thread_checker.h" |
-#include "components/nacl/common/pnacl_types.h" |
-#include "content/public/browser/browser_thread.h" |
-#include "net/base/io_buffer.h" |
-#include "net/base/net_errors.h" |
-#include "net/disk_cache/disk_cache.h" |
- |
-using base::IntToString; |
-using content::BrowserThread; |
- |
-namespace { |
- |
-void CloseDiskCacheEntry(disk_cache::Entry* entry) { entry->Close(); } |
- |
-} // namespace |
- |
-namespace pnacl { |
-// This is in pnacl namespace instead of static so they can be used |
-// by the unit test. |
-const int kMaxMemCacheSize = 100 * 1024 * 1024; |
- |
-////////////////////////////////////////////////////////////////////// |
-// Handle Reading/Writing to Cache. |
- |
-// PnaclTranslationCacheEntry is a shim that provides storage for the |
-// 'key' and 'data' strings as the disk_cache is performing various async |
-// operations. It also tracks the open disk_cache::Entry |
-// and ensures that the entry is closed. |
-class PnaclTranslationCacheEntry |
- : public base::RefCounted<PnaclTranslationCacheEntry> { |
- public: |
- static PnaclTranslationCacheEntry* GetReadEntry( |
- base::WeakPtr<PnaclTranslationCache> cache, |
- const std::string& key, |
- const GetNexeCallback& callback); |
- static PnaclTranslationCacheEntry* GetWriteEntry( |
- base::WeakPtr<PnaclTranslationCache> cache, |
- const std::string& key, |
- net::DrainableIOBuffer* write_nexe, |
- const CompletionCallback& callback); |
- |
- void Start(); |
- |
- // Writes: --- |
- // v | |
- // Start -> Open Existing --------------> Write ---> Close |
- // \ ^ |
- // \ / |
- // --> Create -- |
- // Reads: |
- // Start -> Open --------Read ----> Close |
- // | ^ |
- // |__| |
- enum CacheStep { |
- UNINITIALIZED, |
- OPEN_ENTRY, |
- CREATE_ENTRY, |
- TRANSFER_ENTRY, |
- CLOSE_ENTRY, |
- FINISHED |
- }; |
- |
- private: |
- friend class base::RefCounted<PnaclTranslationCacheEntry>; |
- PnaclTranslationCacheEntry(base::WeakPtr<PnaclTranslationCache> cache, |
- const std::string& key, |
- bool is_read); |
- ~PnaclTranslationCacheEntry(); |
- |
- // Try to open an existing entry in the backend |
- void OpenEntry(); |
- // Create a new entry in the backend (for writes) |
- void CreateEntry(); |
- // Write |len| bytes to the backend, starting at |offset| |
- void WriteEntry(int offset, int len); |
- // Read |len| bytes from the backend, starting at |offset| |
- void ReadEntry(int offset, int len); |
- // If there was an error, doom the entry. Then post a task to the IO |
- // thread to close (and delete) it. |
- void CloseEntry(int rv); |
- // Call the user callback, and signal to the cache to delete this. |
- void Finish(int rv); |
- // Used as the callback for all operations to the backend. Handle state |
- // transitions, track bytes transferred, and call the other helper methods. |
- void DispatchNext(int rv); |
- |
- base::WeakPtr<PnaclTranslationCache> cache_; |
- std::string key_; |
- disk_cache::Entry* entry_; |
- CacheStep step_; |
- bool is_read_; |
- GetNexeCallback read_callback_; |
- CompletionCallback write_callback_; |
- scoped_refptr<net::DrainableIOBuffer> io_buf_; |
- base::ThreadChecker thread_checker_; |
- DISALLOW_COPY_AND_ASSIGN(PnaclTranslationCacheEntry); |
-}; |
- |
-// static |
-PnaclTranslationCacheEntry* PnaclTranslationCacheEntry::GetReadEntry( |
- base::WeakPtr<PnaclTranslationCache> cache, |
- const std::string& key, |
- const GetNexeCallback& callback) { |
- PnaclTranslationCacheEntry* entry( |
- new PnaclTranslationCacheEntry(cache, key, true)); |
- entry->read_callback_ = callback; |
- return entry; |
-} |
- |
-// static |
-PnaclTranslationCacheEntry* PnaclTranslationCacheEntry::GetWriteEntry( |
- base::WeakPtr<PnaclTranslationCache> cache, |
- const std::string& key, |
- net::DrainableIOBuffer* write_nexe, |
- const CompletionCallback& callback) { |
- PnaclTranslationCacheEntry* entry( |
- new PnaclTranslationCacheEntry(cache, key, false)); |
- entry->io_buf_ = write_nexe; |
- entry->write_callback_ = callback; |
- return entry; |
-} |
- |
-PnaclTranslationCacheEntry::PnaclTranslationCacheEntry( |
- base::WeakPtr<PnaclTranslationCache> cache, |
- const std::string& key, |
- bool is_read) |
- : cache_(cache), |
- key_(key), |
- entry_(NULL), |
- step_(UNINITIALIZED), |
- is_read_(is_read) {} |
- |
-PnaclTranslationCacheEntry::~PnaclTranslationCacheEntry() { |
- // Ensure we have called the user's callback |
- if (step_ != FINISHED) { |
- if (!read_callback_.is_null()) { |
- BrowserThread::PostTask( |
- BrowserThread::IO, |
- FROM_HERE, |
- base::Bind(read_callback_, |
- net::ERR_ABORTED, |
- scoped_refptr<net::DrainableIOBuffer>())); |
- } |
- if (!write_callback_.is_null()) { |
- BrowserThread::PostTask(BrowserThread::IO, |
- FROM_HERE, |
- base::Bind(write_callback_, net::ERR_ABORTED)); |
- } |
- } |
-} |
- |
-void PnaclTranslationCacheEntry::Start() { |
- DCHECK(thread_checker_.CalledOnValidThread()); |
- step_ = OPEN_ENTRY; |
- OpenEntry(); |
-} |
- |
-// OpenEntry, CreateEntry, WriteEntry, ReadEntry and CloseEntry are only called |
-// from DispatchNext, so they know that cache_ is still valid. |
-void PnaclTranslationCacheEntry::OpenEntry() { |
- int rv = cache_->backend()->OpenEntry( |
- key_, |
- &entry_, |
- base::Bind(&PnaclTranslationCacheEntry::DispatchNext, this)); |
- if (rv != net::ERR_IO_PENDING) |
- DispatchNext(rv); |
-} |
- |
-void PnaclTranslationCacheEntry::CreateEntry() { |
- int rv = cache_->backend()->CreateEntry( |
- key_, |
- &entry_, |
- base::Bind(&PnaclTranslationCacheEntry::DispatchNext, this)); |
- if (rv != net::ERR_IO_PENDING) |
- DispatchNext(rv); |
-} |
- |
-void PnaclTranslationCacheEntry::WriteEntry(int offset, int len) { |
- DCHECK(io_buf_->BytesRemaining() == len); |
- int rv = entry_->WriteData( |
- 1, |
- offset, |
- io_buf_.get(), |
- len, |
- base::Bind(&PnaclTranslationCacheEntry::DispatchNext, this), |
- false); |
- if (rv != net::ERR_IO_PENDING) |
- DispatchNext(rv); |
-} |
- |
-void PnaclTranslationCacheEntry::ReadEntry(int offset, int len) { |
- int rv = entry_->ReadData( |
- 1, |
- offset, |
- io_buf_.get(), |
- len, |
- base::Bind(&PnaclTranslationCacheEntry::DispatchNext, this)); |
- if (rv != net::ERR_IO_PENDING) |
- DispatchNext(rv); |
-} |
- |
-void PnaclTranslationCacheEntry::CloseEntry(int rv) { |
- DCHECK(entry_); |
- if (rv < 0) { |
- LOG(ERROR) << "Failed to close entry: " << net::ErrorToString(rv); |
- entry_->Doom(); |
- } |
- BrowserThread::PostTask( |
- BrowserThread::IO, FROM_HERE, base::Bind(&CloseDiskCacheEntry, entry_)); |
- Finish(rv); |
-} |
- |
-void PnaclTranslationCacheEntry::Finish(int rv) { |
- step_ = FINISHED; |
- if (is_read_) { |
- if (!read_callback_.is_null()) { |
- BrowserThread::PostTask(BrowserThread::IO, |
- FROM_HERE, |
- base::Bind(read_callback_, rv, io_buf_)); |
- } |
- } else { |
- if (!write_callback_.is_null()) { |
- BrowserThread::PostTask( |
- BrowserThread::IO, FROM_HERE, base::Bind(write_callback_, rv)); |
- } |
- } |
- cache_->OpComplete(this); |
-} |
- |
-void PnaclTranslationCacheEntry::DispatchNext(int rv) { |
- DCHECK(thread_checker_.CalledOnValidThread()); |
- if (!cache_) |
- return; |
- |
- switch (step_) { |
- case UNINITIALIZED: |
- case FINISHED: |
- LOG(ERROR) << "DispatchNext called uninitialized"; |
- break; |
- |
- case OPEN_ENTRY: |
- if (rv == net::OK) { |
- step_ = TRANSFER_ENTRY; |
- if (is_read_) { |
- int bytes_to_transfer = entry_->GetDataSize(1); |
- io_buf_ = new net::DrainableIOBuffer( |
- new net::IOBuffer(bytes_to_transfer), bytes_to_transfer); |
- ReadEntry(0, bytes_to_transfer); |
- } else { |
- WriteEntry(0, io_buf_->size()); |
- } |
- } else { |
- if (rv != net::ERR_FAILED) { |
- // ERROR_FAILED is what we expect if the entry doesn't exist. |
- LOG(ERROR) << "OpenEntry failed: " << net::ErrorToString(rv); |
- } |
- if (is_read_) { |
- // Just a cache miss, not necessarily an error. |
- entry_ = NULL; |
- Finish(rv); |
- } else { |
- step_ = CREATE_ENTRY; |
- CreateEntry(); |
- } |
- } |
- break; |
- |
- case CREATE_ENTRY: |
- if (rv == net::OK) { |
- step_ = TRANSFER_ENTRY; |
- WriteEntry(io_buf_->BytesConsumed(), io_buf_->BytesRemaining()); |
- } else { |
- LOG(ERROR) << "Failed to Create Entry: " << net::ErrorToString(rv); |
- Finish(rv); |
- } |
- break; |
- |
- case TRANSFER_ENTRY: |
- if (rv < 0) { |
- // We do not call DispatchNext directly if WriteEntry/ReadEntry returns |
- // ERR_IO_PENDING, and the callback should not return that value either. |
- LOG(ERROR) << "Failed to complete write to entry: " |
- << net::ErrorToString(rv); |
- step_ = CLOSE_ENTRY; |
- CloseEntry(rv); |
- break; |
- } else if (rv > 0) { |
- io_buf_->DidConsume(rv); |
- if (io_buf_->BytesRemaining() > 0) { |
- is_read_ |
- ? ReadEntry(io_buf_->BytesConsumed(), io_buf_->BytesRemaining()) |
- : WriteEntry(io_buf_->BytesConsumed(), io_buf_->BytesRemaining()); |
- break; |
- } |
- } |
- // rv == 0 or we fell through (i.e. we have transferred all the bytes) |
- step_ = CLOSE_ENTRY; |
- DCHECK(io_buf_->BytesConsumed() == io_buf_->size()); |
- if (is_read_) |
- io_buf_->SetOffset(0); |
- CloseEntry(0); |
- break; |
- |
- case CLOSE_ENTRY: |
- step_ = UNINITIALIZED; |
- break; |
- } |
-} |
- |
-////////////////////////////////////////////////////////////////////// |
-void PnaclTranslationCache::OpComplete(PnaclTranslationCacheEntry* entry) { |
- open_entries_.erase(entry); |
-} |
- |
-////////////////////////////////////////////////////////////////////// |
-// Construction and cache backend initialization |
-PnaclTranslationCache::PnaclTranslationCache() : in_memory_(false) {} |
- |
-PnaclTranslationCache::~PnaclTranslationCache() {} |
- |
-int PnaclTranslationCache::Init(net::CacheType cache_type, |
- const base::FilePath& cache_dir, |
- int cache_size, |
- const CompletionCallback& callback) { |
- int rv = disk_cache::CreateCacheBackend( |
- cache_type, |
- net::CACHE_BACKEND_DEFAULT, |
- cache_dir, |
- cache_size, |
- true /* force_initialize */, |
- BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE).get(), |
- NULL, /* dummy net log */ |
- &disk_cache_, |
- base::Bind(&PnaclTranslationCache::OnCreateBackendComplete, AsWeakPtr())); |
- if (rv == net::ERR_IO_PENDING) { |
- init_callback_ = callback; |
- } |
- return rv; |
-} |
- |
-void PnaclTranslationCache::OnCreateBackendComplete(int rv) { |
- if (rv < 0) { |
- LOG(ERROR) << "Backend init failed:" << net::ErrorToString(rv); |
- } |
- // Invoke our client's callback function. |
- if (!init_callback_.is_null()) { |
- BrowserThread::PostTask( |
- BrowserThread::IO, FROM_HERE, base::Bind(init_callback_, rv)); |
- } |
-} |
- |
-////////////////////////////////////////////////////////////////////// |
-// High-level API |
- |
-void PnaclTranslationCache::StoreNexe(const std::string& key, |
- net::DrainableIOBuffer* nexe_data, |
- const CompletionCallback& callback) { |
- PnaclTranslationCacheEntry* entry = PnaclTranslationCacheEntry::GetWriteEntry( |
- AsWeakPtr(), key, nexe_data, callback); |
- open_entries_[entry] = entry; |
- entry->Start(); |
-} |
- |
-void PnaclTranslationCache::GetNexe(const std::string& key, |
- const GetNexeCallback& callback) { |
- PnaclTranslationCacheEntry* entry = |
- PnaclTranslationCacheEntry::GetReadEntry(AsWeakPtr(), key, callback); |
- open_entries_[entry] = entry; |
- entry->Start(); |
-} |
- |
-int PnaclTranslationCache::InitOnDisk(const base::FilePath& cache_directory, |
- const CompletionCallback& callback) { |
- in_memory_ = false; |
- return Init(net::PNACL_CACHE, cache_directory, 0 /* auto size */, callback); |
-} |
- |
-int PnaclTranslationCache::InitInMemory(const CompletionCallback& callback) { |
- in_memory_ = true; |
- return Init(net::MEMORY_CACHE, base::FilePath(), kMaxMemCacheSize, callback); |
-} |
- |
-int PnaclTranslationCache::Size() { |
- if (!disk_cache_) |
- return -1; |
- return disk_cache_->GetEntryCount(); |
-} |
- |
-// static |
-std::string PnaclTranslationCache::GetKey(const nacl::PnaclCacheInfo& info) { |
- if (!info.pexe_url.is_valid() || info.abi_version < 0 || info.opt_level < 0) |
- return std::string(); |
- std::string retval("ABI:"); |
- retval += IntToString(info.abi_version) + ";" + "opt:" + |
- IntToString(info.opt_level) + ";" + "URL:"; |
- // Filter the username, password, and ref components from the URL |
- GURL::Replacements replacements; |
- replacements.ClearUsername(); |
- replacements.ClearPassword(); |
- replacements.ClearRef(); |
- GURL key_url(info.pexe_url.ReplaceComponents(replacements)); |
- retval += key_url.spec() + ";"; |
- // You would think that there is already code to format base::Time values |
- // somewhere, but I haven't found it yet. In any case, doing it ourselves |
- // here means we can keep the format stable. |
- base::Time::Exploded exploded; |
- info.last_modified.UTCExplode(&exploded); |
- if (info.last_modified.is_null() || !exploded.HasValidValues()) { |
- memset(&exploded, 0, sizeof(exploded)); |
- } |
- retval += "modified:" + IntToString(exploded.year) + ":" + |
- IntToString(exploded.month) + ":" + |
- IntToString(exploded.day_of_month) + ":" + |
- IntToString(exploded.hour) + ":" + IntToString(exploded.minute) + |
- ":" + IntToString(exploded.second) + ":" + |
- IntToString(exploded.millisecond) + ":UTC;"; |
- retval += "etag:" + info.etag; |
- return retval; |
-} |
- |
-int PnaclTranslationCache::DoomEntriesBetween( |
- base::Time initial, |
- base::Time end, |
- const CompletionCallback& callback) { |
- return disk_cache_->DoomEntriesBetween(initial, end, callback); |
-} |
- |
-} // namespace pnacl |