Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1880)

Unified Diff: chrome/browser/nacl_host/pnacl_translation_cache.cc

Issue 15647018: Add read support to PNaClTranslationCache (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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
index 8316ba7052137881205682015efe67f1ba7f657e..b7f8a366fa31d980265698ffd566402a1efaf904 100644
--- a/chrome/browser/nacl_host/pnacl_translation_cache.cc
+++ b/chrome/browser/nacl_host/pnacl_translation_cache.cc
@@ -33,80 +33,99 @@ const int kMaxDiskCacheSize = 1000 * 1024 * 1024;
const int kMaxMemCacheSize = 100 * 1024 * 1024;
//////////////////////////////////////////////////////////////////////
-// Handle Storing to Cache.
+// Handle Reading/Writing to Cache.
-// PNaClTranslationCacheWriteEntry is a shim that provides storage for the
+// 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 PNaClTranslationCacheWriteEntry
- : public base::RefCounted<PNaClTranslationCacheWriteEntry> {
+class PNaClTranslationCacheEntry
+ : public base::RefCounted<PNaClTranslationCacheEntry> {
public:
- PNaClTranslationCacheWriteEntry(base::WeakPtr<PNaClTranslationCache> cache,
- const std::string& key,
- const std::string& nexe,
- const net::CompletionCallback& callback);
+ PNaClTranslationCacheEntry(base::WeakPtr<PNaClTranslationCache> cache,
+ const std::string& key,
+ std::string* nexe,
+ const CompletionCallback& callback,
+ bool is_read);
- void Cache();
+ void Start();
- // ---
+ // Writes: ---
// v |
- // Cache -> Open Existing --------------> Write ---> Close
+ // Start -> Open Existing --------------> Write ---> Close
// \ ^
// \ /
// --> Create --
+ // Reads:
+ // Start -> Open --------Read ----> Close
+ // | ^
+ // |__|
enum CacheStep {
UNINITIALIZED,
OPEN_ENTRY,
CREATE_ENTRY,
- WRITE_ENTRY,
+ TRANSFER_ENTRY,
CLOSE_ENTRY
};
private:
- friend class base::RefCounted<PNaClTranslationCacheWriteEntry>;
- ~PNaClTranslationCacheWriteEntry();
+ friend class base::RefCounted<PNaClTranslationCacheEntry>;
+ ~PNaClTranslationCacheEntry();
void CreateEntry();
void OpenEntry();
- void WriteEntry(int bytes_to_skip);
+ void WriteEntry(int offset, int len);
+ void ReadEntry(int offset, int len);
jvoung (off chromium) 2013/06/05 00:42:28 extra space between functions to be consistent
Derek Schuff 2013/06/05 05:01:59 even better; made consistent and added comments.
void CloseEntry(int rv);
+ // Handles state transitions, tracks bytes transferred
void DispatchNext(int rv);
+ // Get the total transfer size. For reads, must be called after the entry
+ // has been info has been fetched from the backend.
+ int GetTransferSize();
+
base::WeakPtr<PNaClTranslationCache> cache_;
std::string key_;
- std::string nexe_;
+ std::string* nexe_;
disk_cache::Entry* entry_;
CacheStep step_;
+ bool is_read_;
+ int bytes_transferred_;
+ int bytes_to_transfer_;
+ scoped_refptr<net::IOBufferWithSize> read_buf_;
CompletionCallback finish_callback_;
base::ThreadChecker thread_checker_;
- DISALLOW_COPY_AND_ASSIGN(PNaClTranslationCacheWriteEntry);
+ DISALLOW_COPY_AND_ASSIGN(PNaClTranslationCacheEntry);
};
-PNaClTranslationCacheWriteEntry::PNaClTranslationCacheWriteEntry(
+PNaClTranslationCacheEntry::PNaClTranslationCacheEntry(
base::WeakPtr<PNaClTranslationCache> cache,
const std::string& key,
- const std::string& nexe,
- const net::CompletionCallback& callback)
+ std::string* nexe,
+ const CompletionCallback& callback,
+ bool is_read)
: cache_(cache),
key_(key),
nexe_(nexe),
entry_(NULL),
step_(UNINITIALIZED),
+ is_read_(is_read),
+ bytes_transferred_(0),
+ bytes_to_transfer_(-1),
finish_callback_(callback) {}
-PNaClTranslationCacheWriteEntry::~PNaClTranslationCacheWriteEntry() {
+PNaClTranslationCacheEntry::~PNaClTranslationCacheEntry() {
if (entry_)
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE, base::Bind(&CloseDiskCacheEntry, entry_));
}
-void PNaClTranslationCacheWriteEntry::Cache() {
+void PNaClTranslationCacheEntry::Start() {
DCHECK(thread_checker_.CalledOnValidThread());
step_ = OPEN_ENTRY;
OpenEntry();
@@ -114,49 +133,71 @@ void PNaClTranslationCacheWriteEntry::Cache() {
// OpenEntry, CreateEntry, WriteEntry, and CloseEntry are only called from
// DispatchNext, so they know that cache_ is still valid.
-void PNaClTranslationCacheWriteEntry::OpenEntry() {
- int rv = cache_->backend()->OpenEntry(
- key_,
- &entry_,
- base::Bind(&PNaClTranslationCacheWriteEntry::DispatchNext, this));
+void PNaClTranslationCacheEntry::OpenEntry() {
+ int rv = cache_->backend()
+ ->OpenEntry(key_,
+ &entry_,
+ base::Bind(&PNaClTranslationCacheEntry::DispatchNext, this));
if (rv != net::ERR_IO_PENDING)
DispatchNext(rv);
}
-void PNaClTranslationCacheWriteEntry::CreateEntry() {
+void PNaClTranslationCacheEntry::CreateEntry() {
int rv = cache_->backend()->CreateEntry(
key_,
&entry_,
- base::Bind(&PNaClTranslationCacheWriteEntry::DispatchNext, this));
+ base::Bind(&PNaClTranslationCacheEntry::DispatchNext, this));
if (rv != net::ERR_IO_PENDING)
DispatchNext(rv);
}
-void PNaClTranslationCacheWriteEntry::WriteEntry(int bytes_to_skip) {
- nexe_ = nexe_.substr(bytes_to_skip);
- scoped_refptr<net::StringIOBuffer> io_buf = new net::StringIOBuffer(nexe_);
+void PNaClTranslationCacheEntry::WriteEntry(int offset, int len) {
+ scoped_refptr<net::StringIOBuffer> io_buf =
+ new net::StringIOBuffer(nexe_->substr(offset, len));
int rv = entry_->WriteData(
1,
- 0,
+ offset,
io_buf,
- nexe_.length(),
- base::Bind(&PNaClTranslationCacheWriteEntry::DispatchNext, this),
+ len,
+ base::Bind(&PNaClTranslationCacheEntry::DispatchNext, this),
false);
if (rv != net::ERR_IO_PENDING)
DispatchNext(rv);
}
-void PNaClTranslationCacheWriteEntry::CloseEntry(int rv) {
- if (rv < 0)
+void PNaClTranslationCacheEntry::ReadEntry(int offset, int len) {
+ read_buf_ = new net::IOBufferWithSize(len);
+ int rv = entry_->ReadData(
+ 1,
+ offset,
+ read_buf_,
+ len,
+ base::Bind(&PNaClTranslationCacheEntry::DispatchNext, this));
+ if (rv != net::ERR_IO_PENDING)
+ DispatchNext(rv);
+}
+
+int PNaClTranslationCacheEntry::GetTransferSize() {
+ if (is_read_) {
+ DCHECK(entry_);
+ return entry_->GetDataSize(1);
+ }
+ return nexe_->size();
+}
+
+void PNaClTranslationCacheEntry::CloseEntry(int rv) {
+ if (entry_ && rv < 0)
entry_->Doom();
if (!finish_callback_.is_null()) {
finish_callback_.Run(rv);
finish_callback_.Reset();
}
- cache_->WriteComplete(this);
+ if (!is_read_)
+ delete nexe_;
jvoung (off chromium) 2013/06/05 00:42:28 Perhaps the nexe shouldn't be the same field for b
Derek Schuff 2013/06/05 05:01:59 Yeah, we need to call CloseEntry anyway. Actually
jvoung (off chromium) 2013/06/05 17:52:29 Well, I think static factories might be better so
+ cache_->OpComplete(this);
}
-void PNaClTranslationCacheWriteEntry::DispatchNext(int rv) {
+void PNaClTranslationCacheEntry::DispatchNext(int rv) {
DCHECK(thread_checker_.CalledOnValidThread());
if (!cache_)
return;
@@ -168,9 +209,17 @@ void PNaClTranslationCacheWriteEntry::DispatchNext(int rv) {
case OPEN_ENTRY:
if (rv == net::OK) {
- step_ = WRITE_ENTRY;
- WriteEntry(0);
+ step_ = TRANSFER_ENTRY;
+ bytes_to_transfer_ = GetTransferSize();
+ is_read_ ? ReadEntry(0, bytes_to_transfer_)
+ : WriteEntry(0, bytes_to_transfer_);
} else {
+ if (is_read_) {
+ // Just a cache miss, not necessarily an error.
+ entry_ = NULL;
jvoung (off chromium) 2013/06/05 00:42:28 It looks a bit odd to set entry_ to NULL then call
Derek Schuff 2013/06/05 05:01:59 Done.
+ CloseEntry(rv);
+ break;
+ }
step_ = CREATE_ENTRY;
CreateEntry();
}
@@ -178,15 +227,16 @@ void PNaClTranslationCacheWriteEntry::DispatchNext(int rv) {
case CREATE_ENTRY:
if (rv == net::OK) {
- step_ = WRITE_ENTRY;
- WriteEntry(0);
+ step_ = TRANSFER_ENTRY;
+ bytes_to_transfer_ = GetTransferSize();
+ WriteEntry(bytes_transferred_, bytes_to_transfer_ - bytes_transferred_);
} else {
- LOG(ERROR) << "Failed to Open/Create a PNaCl Translation Cache Entry";
+ LOG(ERROR) << "Failed to Create a PNaCl Translation Cache Entry";
CloseEntry(rv);
}
break;
- case WRITE_ENTRY:
+ case TRANSFER_ENTRY:
if (rv < 0) {
// We do not call DispatchNext directly if WriteEntry returns
jvoung (off chromium) 2013/06/05 00:42:28 WriteEntry or ReadEntry now.
Derek Schuff 2013/06/05 05:01:59 Done.
// ERR_IO_PENDING, and the callback should not return that value either.
@@ -196,15 +246,21 @@ void PNaClTranslationCacheWriteEntry::DispatchNext(int rv) {
step_ = CLOSE_ENTRY;
CloseEntry(rv);
break;
+ } else if (rv > 0) {
+ // For reads, copy the data that was just returned
+ if (is_read_)
+ nexe_->append(read_buf_->data(), rv);
+ bytes_transferred_ += rv;
+ if (bytes_transferred_ < bytes_to_transfer_) {
+ int len = bytes_to_transfer_ - bytes_transferred_;
+ is_read_ ? ReadEntry(bytes_transferred_, len)
+ : WriteEntry(bytes_transferred_, len);
+ break;
+ }
}
- if (rv == 0) {
- step_ = CLOSE_ENTRY;
- CloseEntry(rv);
- break;
- }
- // rv bytes were written; call WriteEntry again to skip them and try to
- // write the rest.
- WriteEntry(rv);
+ // rv == 0 or we fell through (i.e. we have transferred all the bytes)
+ step_ = CLOSE_ENTRY;
+ CloseEntry(0);
break;
case CLOSE_ENTRY:
@@ -214,8 +270,7 @@ void PNaClTranslationCacheWriteEntry::DispatchNext(int rv) {
}
//////////////////////////////////////////////////////////////////////
-void PNaClTranslationCache::WriteComplete(
- PNaClTranslationCacheWriteEntry* entry) {
+void PNaClTranslationCache::OpComplete(PNaClTranslationCacheEntry* entry) {
write_entries_.erase(entry);
}
@@ -224,27 +279,25 @@ void PNaClTranslationCache::WriteComplete(
PNaClTranslationCache::PNaClTranslationCache()
: disk_cache_(NULL), in_memory_(false) {}
-PNaClTranslationCache::~PNaClTranslationCache() {
- delete disk_cache_;
-}
+PNaClTranslationCache::~PNaClTranslationCache() { delete disk_cache_; }
int PNaClTranslationCache::InitWithDiskBackend(
const base::FilePath& cache_dir,
int cache_size,
- const net::CompletionCallback& callback) {
+ const CompletionCallback& callback) {
return Init(net::DISK_CACHE, cache_dir, cache_size, callback);
}
int PNaClTranslationCache::InitWithMemBackend(
int cache_size,
- const net::CompletionCallback& callback) {
+ const CompletionCallback& callback) {
return Init(net::MEMORY_CACHE, base::FilePath(), cache_size, callback);
}
int PNaClTranslationCache::Init(net::CacheType cache_type,
const base::FilePath& cache_dir,
int cache_size,
- const net::CompletionCallback& callback) {
+ const CompletionCallback& callback) {
int rv = disk_cache::CreateCacheBackend(
cache_type,
net::CACHE_BACKEND_DEFAULT,
@@ -273,35 +326,32 @@ void PNaClTranslationCache::OnCreateBackendComplete(int rv) {
//////////////////////////////////////////////////////////////////////
// High-level API
-// TODO(dschuff): Surely there must be a way to just create a null callback?
-static void NullCallback(int ignored) {}
-
void PNaClTranslationCache::StoreNexe(const std::string& key,
const std::string& nexe) {
- StoreNexe(key, nexe, base::Bind(NullCallback));
+ StoreNexe(key, nexe, CompletionCallback());
}
void PNaClTranslationCache::StoreNexe(const std::string& key,
const std::string& nexe,
- const net::CompletionCallback& callback) {
- PNaClTranslationCacheWriteEntry* entry =
- new PNaClTranslationCacheWriteEntry(AsWeakPtr(), key, nexe, callback);
+ const CompletionCallback& callback) {
+ PNaClTranslationCacheEntry* entry = new PNaClTranslationCacheEntry(
+ AsWeakPtr(), key, new std::string(nexe), callback, false);
write_entries_[entry] = entry;
- entry->Cache();
+ entry->Start();
}
-int PNaClTranslationCache::GetNexe(const std::string& key,
- std::string* nexe,
- const net::CompletionCallback& callback) {
- // TODO(dschuff): Actually find the entry, and do the right thing.
- // Shader cache ended up making a separate ReadHelper, analogous
- // to the PNaClTranslationCacheWriteEntry.
- return net::OK;
+void PNaClTranslationCache::GetNexe(const std::string& key,
+ std::string* nexe,
+ const CompletionCallback& callback) {
+ PNaClTranslationCacheEntry* entry =
+ new PNaClTranslationCacheEntry(AsWeakPtr(), key, nexe, callback, true);
+ write_entries_[entry] = entry;
+ entry->Start();
}
int PNaClTranslationCache::InitCache(const base::FilePath& cache_directory,
bool in_memory,
- const net::CompletionCallback& callback) {
+ const CompletionCallback& callback) {
int rv;
in_memory_ = in_memory;
if (in_memory_) {

Powered by Google App Engine
This is Rietveld 408576698