Chromium Code Reviews| OLD | NEW | 
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "chrome/browser/nacl_host/pnacl_translation_cache.h" | 5 #include "chrome/browser/nacl_host/pnacl_translation_cache.h" | 
| 6 | 6 | 
| 7 #include <string> | 7 #include <string> | 
| 8 | 8 | 
| 9 #include "base/files/file_path.h" | 9 #include "base/files/file_path.h" | 
| 10 #include "base/logging.h" | 10 #include "base/logging.h" | 
| 11 #include "base/strings/string_number_conversions.h" | |
| 11 #include "base/threading/thread_checker.h" | 12 #include "base/threading/thread_checker.h" | 
| 13 #include "components/nacl/common/pnacl_types.h" | |
| 12 #include "content/public/browser/browser_thread.h" | 14 #include "content/public/browser/browser_thread.h" | 
| 13 #include "net/base/io_buffer.h" | 15 #include "net/base/io_buffer.h" | 
| 14 #include "net/base/net_errors.h" | 16 #include "net/base/net_errors.h" | 
| 15 #include "net/disk_cache/disk_cache.h" | 17 #include "net/disk_cache/disk_cache.h" | 
| 16 | 18 | 
| 19 using base::IntToString; | |
| 17 using content::BrowserThread; | 20 using content::BrowserThread; | 
| 18 | 21 | 
| 19 namespace { | 22 namespace { | 
| 20 | 23 | 
| 21 void CloseDiskCacheEntry(disk_cache::Entry* entry) { entry->Close(); } | 24 void CloseDiskCacheEntry(disk_cache::Entry* entry) { entry->Close(); } | 
| 22 | 25 | 
| 23 } // namespace | 26 } // namespace | 
| 24 | 27 | 
| 25 namespace pnacl { | 28 namespace pnacl { | 
| 26 // These are in pnacl_cache namespace instead of static so they can be used | 29 // These are in pnacl namespace instead of static so they can be used | 
| 27 // by the unit test. | 30 // by the unit test. | 
| 28 const int kMaxDiskCacheSize = 1000 * 1024 * 1024; | 31 const int kMaxDiskCacheSize = 1000 * 1024 * 1024; | 
| 29 const int kMaxMemCacheSize = 100 * 1024 * 1024; | 32 const int kMaxMemCacheSize = 100 * 1024 * 1024; | 
| 30 | 33 | 
| 31 ////////////////////////////////////////////////////////////////////// | 34 ////////////////////////////////////////////////////////////////////// | 
| 32 // Handle Reading/Writing to Cache. | 35 // Handle Reading/Writing to Cache. | 
| 33 | 36 | 
| 34 // PnaclTranslationCacheEntry is a shim that provides storage for the | 37 // PnaclTranslationCacheEntry is a shim that provides storage for the | 
| 35 // 'key' and 'data' strings as the disk_cache is performing various async | 38 // 'key' and 'data' strings as the disk_cache is performing various async | 
| 36 // operations. It also tracks the open disk_cache::Entry | 39 // operations. It also tracks the open disk_cache::Entry | 
| 37 // and ensures that the entry is closed. | 40 // and ensures that the entry is closed. | 
| 38 class PnaclTranslationCacheEntry | 41 class PnaclTranslationCacheEntry | 
| 39 : public base::RefCounted<PnaclTranslationCacheEntry> { | 42 : public base::RefCounted<PnaclTranslationCacheEntry> { | 
| 40 public: | 43 public: | 
| 41 PnaclTranslationCacheEntry(base::WeakPtr<PnaclTranslationCache> cache, | 44 static PnaclTranslationCacheEntry* GetReadEntry( | 
| 42 const std::string& key, | 45 base::WeakPtr<PnaclTranslationCache> cache, | 
| 43 std::string* read_nexe, | 46 const std::string& key, | 
| 44 const std::string& write_nexe, | 47 const NexeCallback& callback); | 
| 45 const CompletionCallback& callback, | 48 static PnaclTranslationCacheEntry* GetWriteEntry( | 
| 46 bool is_read); | 49 base::WeakPtr<PnaclTranslationCache> cache, | 
| 50 const std::string& key, | |
| 51 net::DrainableIOBuffer* write_nexe, | |
| 52 const CompletionCallback& callback); | |
| 53 | |
| 47 void Start(); | 54 void Start(); | 
| 48 | 55 | 
| 49 // Writes: --- | 56 // Writes: --- | 
| 50 // v | | 57 // v | | 
| 51 // Start -> Open Existing --------------> Write ---> Close | 58 // Start -> Open Existing --------------> Write ---> Close | 
| 52 // \ ^ | 59 // \ ^ | 
| 53 // \ / | 60 // \ / | 
| 54 // --> Create -- | 61 // --> Create -- | 
| 55 // Reads: | 62 // Reads: | 
| 56 // Start -> Open --------Read ----> Close | 63 // Start -> Open --------Read ----> Close | 
| 57 // | ^ | 64 // | ^ | 
| 58 // |__| | 65 // |__| | 
| 59 enum CacheStep { | 66 enum CacheStep { | 
| 60 UNINITIALIZED, | 67 UNINITIALIZED, | 
| 61 OPEN_ENTRY, | 68 OPEN_ENTRY, | 
| 62 CREATE_ENTRY, | 69 CREATE_ENTRY, | 
| 63 TRANSFER_ENTRY, | 70 TRANSFER_ENTRY, | 
| 64 CLOSE_ENTRY | 71 CLOSE_ENTRY | 
| 65 }; | 72 }; | 
| 66 | 73 | 
| 67 private: | 74 private: | 
| 68 friend class base::RefCounted<PnaclTranslationCacheEntry>; | 75 friend class base::RefCounted<PnaclTranslationCacheEntry>; | 
| 76 PnaclTranslationCacheEntry(base::WeakPtr<PnaclTranslationCache> cache, | |
| 77 const std::string& key, | |
| 78 bool is_read); | |
| 69 ~PnaclTranslationCacheEntry(); | 79 ~PnaclTranslationCacheEntry(); | 
| 70 | 80 | 
| 71 // Try to open an existing entry in the backend | 81 // Try to open an existing entry in the backend | 
| 72 void OpenEntry(); | 82 void OpenEntry(); | 
| 73 // Create a new entry in the backend (for writes) | 83 // Create a new entry in the backend (for writes) | 
| 74 void CreateEntry(); | 84 void CreateEntry(); | 
| 75 // Write |len| bytes to the backend, starting at |offset| | 85 // Write |len| bytes to the backend, starting at |offset| | 
| 76 void WriteEntry(int offset, int len); | 86 void WriteEntry(int offset, int len); | 
| 77 // Read |len| bytes from the backend, starting at |offset| | 87 // Read |len| bytes from the backend, starting at |offset| | 
| 78 void ReadEntry(int offset, int len); | 88 void ReadEntry(int offset, int len); | 
| 79 // If there was an error, doom the entry. Then post a task to the IO | 89 // If there was an error, doom the entry. Then post a task to the IO | 
| 80 // thread to close (and delete) it. | 90 // thread to close (and delete) it. | 
| 81 void CloseEntry(int rv); | 91 void CloseEntry(int rv); | 
| 82 // Call the user callback, and signal to the cache to delete this. | 92 // Call the user callback, and signal to the cache to delete this. | 
| 83 void Finish(int rv); | 93 void Finish(int rv); | 
| 84 // Used as the callback for all operations to the backend. Handle state | 94 // Used as the callback for all operations to the backend. Handle state | 
| 85 // transitions, track bytes transferred, and call the other helper methods. | 95 // transitions, track bytes transferred, and call the other helper methods. | 
| 86 void DispatchNext(int rv); | 96 void DispatchNext(int rv); | 
| 87 // Get the total transfer size. For reads, must be called after the backend | |
| 88 // entry has been opened. | |
| 89 int GetTransferSize(); | |
| 90 | 97 | 
| 91 base::WeakPtr<PnaclTranslationCache> cache_; | 98 base::WeakPtr<PnaclTranslationCache> cache_; | 
| 92 | |
| 93 std::string key_; | 99 std::string key_; | 
| 94 std::string* read_nexe_; | |
| 95 std::string write_nexe_; | |
| 96 disk_cache::Entry* entry_; | 100 disk_cache::Entry* entry_; | 
| 97 CacheStep step_; | 101 CacheStep step_; | 
| 98 bool is_read_; | 102 bool is_read_; | 
| 99 int bytes_transferred_; | 103 NexeCallback read_callback_; | 
| 100 int bytes_to_transfer_; | 104 CompletionCallback write_callback_; | 
| 101 scoped_refptr<net::IOBufferWithSize> read_buf_; | 105 scoped_refptr<net::DrainableIOBuffer> io_buf_; | 
| 102 CompletionCallback finish_callback_; | |
| 103 base::ThreadChecker thread_checker_; | 106 base::ThreadChecker thread_checker_; | 
| 104 DISALLOW_COPY_AND_ASSIGN(PnaclTranslationCacheEntry); | 107 DISALLOW_COPY_AND_ASSIGN(PnaclTranslationCacheEntry); | 
| 105 }; | 108 }; | 
| 106 | 109 | 
| 110 // static | |
| 111 PnaclTranslationCacheEntry* PnaclTranslationCacheEntry::GetReadEntry( | |
| 112 base::WeakPtr<PnaclTranslationCache> cache, | |
| 113 const std::string& key, | |
| 114 const NexeCallback& callback) { | |
| 115 PnaclTranslationCacheEntry* entry( | |
| 116 new PnaclTranslationCacheEntry(cache, key, true)); | |
| 117 entry->read_callback_ = callback; | |
| 118 return entry; | |
| 119 } | |
| 120 | |
| 121 // static | |
| 122 PnaclTranslationCacheEntry* PnaclTranslationCacheEntry::GetWriteEntry( | |
| 123 base::WeakPtr<PnaclTranslationCache> cache, | |
| 124 const std::string& key, | |
| 125 net::DrainableIOBuffer* write_nexe, | |
| 126 const CompletionCallback& callback) { | |
| 127 PnaclTranslationCacheEntry* entry( | |
| 128 new PnaclTranslationCacheEntry(cache, key, false)); | |
| 129 entry->io_buf_ = write_nexe; | |
| 130 entry->write_callback_ = callback; | |
| 131 return entry; | |
| 132 } | |
| 133 | |
| 107 PnaclTranslationCacheEntry::PnaclTranslationCacheEntry( | 134 PnaclTranslationCacheEntry::PnaclTranslationCacheEntry( | 
| 108 base::WeakPtr<PnaclTranslationCache> cache, | 135 base::WeakPtr<PnaclTranslationCache> cache, | 
| 109 const std::string& key, | 136 const std::string& key, | 
| 110 std::string* read_nexe, | |
| 111 const std::string& write_nexe, | |
| 112 const CompletionCallback& callback, | |
| 113 bool is_read) | 137 bool is_read) | 
| 114 : cache_(cache), | 138 : cache_(cache), | 
| 115 key_(key), | 139 key_(key), | 
| 116 read_nexe_(read_nexe), | |
| 117 write_nexe_(write_nexe), | |
| 118 entry_(NULL), | 140 entry_(NULL), | 
| 119 step_(UNINITIALIZED), | 141 step_(UNINITIALIZED), | 
| 120 is_read_(is_read), | 142 is_read_(is_read) {} | 
| 121 bytes_transferred_(0), | |
| 122 bytes_to_transfer_(-1), | |
| 123 finish_callback_(callback) {} | |
| 124 | 143 | 
| 125 PnaclTranslationCacheEntry::~PnaclTranslationCacheEntry() { | 144 PnaclTranslationCacheEntry::~PnaclTranslationCacheEntry() { | 
| 126 // Ensure we have called the user's callback | 145 // Ensure we have called the user's callback | 
| 127 DCHECK(finish_callback_.is_null()); | 146 DCHECK(read_callback_.is_null()); | 
| 147 DCHECK(write_callback_.is_null()); | |
| 128 } | 148 } | 
| 129 | 149 | 
| 130 void PnaclTranslationCacheEntry::Start() { | 150 void PnaclTranslationCacheEntry::Start() { | 
| 131 DCHECK(thread_checker_.CalledOnValidThread()); | 151 DCHECK(thread_checker_.CalledOnValidThread()); | 
| 132 step_ = OPEN_ENTRY; | 152 step_ = OPEN_ENTRY; | 
| 133 OpenEntry(); | 153 OpenEntry(); | 
| 134 } | 154 } | 
| 135 | 155 | 
| 136 // OpenEntry, CreateEntry, WriteEntry, ReadEntry and CloseEntry are only called | 156 // OpenEntry, CreateEntry, WriteEntry, ReadEntry and CloseEntry are only called | 
| 137 // from DispatchNext, so they know that cache_ is still valid. | 157 // from DispatchNext, so they know that cache_ is still valid. | 
| 138 void PnaclTranslationCacheEntry::OpenEntry() { | 158 void PnaclTranslationCacheEntry::OpenEntry() { | 
| 139 int rv = cache_->backend() | 159 int rv = cache_->backend() | 
| 140 ->OpenEntry(key_, | 160 ->OpenEntry(key_, | 
| 141 &entry_, | 161 &entry_, | 
| 142 base::Bind(&PnaclTranslationCacheEntry::DispatchNext, this)); | 162 base::Bind(&PnaclTranslationCacheEntry::DispatchNext, this)); | 
| 143 if (rv != net::ERR_IO_PENDING) | 163 if (rv != net::ERR_IO_PENDING) | 
| 144 DispatchNext(rv); | 164 DispatchNext(rv); | 
| 145 } | 165 } | 
| 146 | 166 | 
| 147 void PnaclTranslationCacheEntry::CreateEntry() { | 167 void PnaclTranslationCacheEntry::CreateEntry() { | 
| 148 int rv = cache_->backend()->CreateEntry( | 168 int rv = cache_->backend()->CreateEntry( | 
| 149 key_, | 169 key_, | 
| 150 &entry_, | 170 &entry_, | 
| 151 base::Bind(&PnaclTranslationCacheEntry::DispatchNext, this)); | 171 base::Bind(&PnaclTranslationCacheEntry::DispatchNext, this)); | 
| 152 if (rv != net::ERR_IO_PENDING) | 172 if (rv != net::ERR_IO_PENDING) | 
| 153 DispatchNext(rv); | 173 DispatchNext(rv); | 
| 154 } | 174 } | 
| 155 | 175 | 
| 156 void PnaclTranslationCacheEntry::WriteEntry(int offset, int len) { | 176 void PnaclTranslationCacheEntry::WriteEntry(int offset, int len) { | 
| 157 scoped_refptr<net::StringIOBuffer> io_buf = | 177 DCHECK(io_buf_->BytesRemaining() == len); | 
| 158 new net::StringIOBuffer(write_nexe_.substr(offset, len)); | |
| 159 int rv = entry_->WriteData( | 178 int rv = entry_->WriteData( | 
| 160 1, | 179 1, | 
| 161 offset, | 180 offset, | 
| 162 io_buf.get(), | 181 io_buf_.get(), | 
| 163 len, | 182 len, | 
| 164 base::Bind(&PnaclTranslationCacheEntry::DispatchNext, this), | 183 base::Bind(&PnaclTranslationCacheEntry::DispatchNext, this), | 
| 165 false); | 184 false); | 
| 166 if (rv != net::ERR_IO_PENDING) | 185 if (rv != net::ERR_IO_PENDING) | 
| 167 DispatchNext(rv); | 186 DispatchNext(rv); | 
| 168 } | 187 } | 
| 169 | 188 | 
| 170 void PnaclTranslationCacheEntry::ReadEntry(int offset, int len) { | 189 void PnaclTranslationCacheEntry::ReadEntry(int offset, int len) { | 
| 171 read_buf_ = new net::IOBufferWithSize(len); | |
| 172 int rv = entry_->ReadData( | 190 int rv = entry_->ReadData( | 
| 173 1, | 191 1, | 
| 174 offset, | 192 offset, | 
| 175 read_buf_.get(), | 193 io_buf_.get(), | 
| 176 len, | 194 len, | 
| 177 base::Bind(&PnaclTranslationCacheEntry::DispatchNext, this)); | 195 base::Bind(&PnaclTranslationCacheEntry::DispatchNext, this)); | 
| 178 if (rv != net::ERR_IO_PENDING) | 196 if (rv != net::ERR_IO_PENDING) | 
| 179 DispatchNext(rv); | 197 DispatchNext(rv); | 
| 180 } | 198 } | 
| 181 | 199 | 
| 182 int PnaclTranslationCacheEntry::GetTransferSize() { | |
| 183 if (is_read_) { | |
| 184 DCHECK(entry_); | |
| 185 return entry_->GetDataSize(1); | |
| 186 } | |
| 187 return write_nexe_.size(); | |
| 188 } | |
| 189 | |
| 190 void PnaclTranslationCacheEntry::CloseEntry(int rv) { | 200 void PnaclTranslationCacheEntry::CloseEntry(int rv) { | 
| 191 DCHECK(entry_); | 201 DCHECK(entry_); | 
| 192 if (rv < 0) | 202 if (rv < 0) | 
| 193 entry_->Doom(); | 203 entry_->Doom(); | 
| 194 BrowserThread::PostTask( | 204 BrowserThread::PostTask( | 
| 195 BrowserThread::IO, FROM_HERE, base::Bind(&CloseDiskCacheEntry, entry_)); | 205 BrowserThread::IO, FROM_HERE, base::Bind(&CloseDiskCacheEntry, entry_)); | 
| 196 Finish(rv); | 206 Finish(rv); | 
| 197 } | 207 } | 
| 198 | 208 | 
| 199 void PnaclTranslationCacheEntry::Finish(int rv) { | 209 void PnaclTranslationCacheEntry::Finish(int rv) { | 
| 200 if (!finish_callback_.is_null()) { | 210 if (is_read_) { | 
| 201 finish_callback_.Run(rv); | 211 if (!read_callback_.is_null()) { | 
| 202 finish_callback_.Reset(); | 212 read_callback_.Run(rv, io_buf_); | 
| 213 read_callback_.Reset(); | |
| 214 } | |
| 215 } else { | |
| 216 if (!write_callback_.is_null()) { | |
| 217 write_callback_.Run(rv); | |
| 218 write_callback_.Reset(); | |
| 219 } | |
| 203 } | 220 } | 
| 204 cache_->OpComplete(this); | 221 cache_->OpComplete(this); | 
| 205 } | 222 } | 
| 206 | 223 | 
| 207 void PnaclTranslationCacheEntry::DispatchNext(int rv) { | 224 void PnaclTranslationCacheEntry::DispatchNext(int rv) { | 
| 208 DCHECK(thread_checker_.CalledOnValidThread()); | 225 DCHECK(thread_checker_.CalledOnValidThread()); | 
| 209 if (!cache_) | 226 if (!cache_) | 
| 210 return; | 227 return; | 
| 211 | 228 | 
| 212 switch (step_) { | 229 switch (step_) { | 
| 213 case UNINITIALIZED: | 230 case UNINITIALIZED: | 
| 214 LOG(ERROR) << "Unexpected step in DispatchNext"; | 231 LOG(ERROR) << "Unexpected step in DispatchNext"; | 
| 215 break; | 232 break; | 
| 216 | 233 | 
| 217 case OPEN_ENTRY: | 234 case OPEN_ENTRY: | 
| 218 if (rv == net::OK) { | 235 if (rv == net::OK) { | 
| 219 step_ = TRANSFER_ENTRY; | 236 step_ = TRANSFER_ENTRY; | 
| 220 bytes_to_transfer_ = GetTransferSize(); | 237 if (is_read_) { | 
| 221 is_read_ ? ReadEntry(0, bytes_to_transfer_) | 238 int bytes_to_transfer = entry_->GetDataSize(1); | 
| 222 : WriteEntry(0, bytes_to_transfer_); | 239 io_buf_ = new net::DrainableIOBuffer( | 
| 240 new net::IOBuffer(bytes_to_transfer), bytes_to_transfer); | |
| 241 ReadEntry(0, bytes_to_transfer); | |
| 242 } else { | |
| 243 WriteEntry(0, io_buf_->size()); | |
| 244 } | |
| 223 } else { | 245 } else { | 
| 224 if (is_read_) { | 246 if (is_read_) { | 
| 225 // Just a cache miss, not necessarily an error. | 247 // Just a cache miss, not necessarily an error. | 
| 226 entry_ = NULL; | 248 entry_ = NULL; | 
| 227 Finish(rv); | 249 Finish(rv); | 
| 228 break; | 250 } else { | 
| 251 step_ = CREATE_ENTRY; | |
| 252 CreateEntry(); | |
| 229 } | 253 } | 
| 230 step_ = CREATE_ENTRY; | |
| 231 CreateEntry(); | |
| 232 } | 254 } | 
| 233 break; | 255 break; | 
| 234 | 256 | 
| 235 case CREATE_ENTRY: | 257 case CREATE_ENTRY: | 
| 236 if (rv == net::OK) { | 258 if (rv == net::OK) { | 
| 237 step_ = TRANSFER_ENTRY; | 259 step_ = TRANSFER_ENTRY; | 
| 238 bytes_to_transfer_ = GetTransferSize(); | 260 WriteEntry(io_buf_->BytesConsumed(), io_buf_->BytesRemaining()); | 
| 239 WriteEntry(bytes_transferred_, bytes_to_transfer_ - bytes_transferred_); | |
| 240 } else { | 261 } else { | 
| 241 LOG(ERROR) << "Failed to Create a PNaCl Translation Cache Entry"; | 262 LOG(ERROR) << "Failed to Create a PNaCl Translation Cache Entry"; | 
| 242 Finish(rv); | 263 Finish(rv); | 
| 243 } | 264 } | 
| 244 break; | 265 break; | 
| 245 | 266 | 
| 246 case TRANSFER_ENTRY: | 267 case TRANSFER_ENTRY: | 
| 247 if (rv < 0) { | 268 if (rv < 0) { | 
| 248 // We do not call DispatchNext directly if WriteEntry/ReadEntry returns | 269 // We do not call DispatchNext directly if WriteEntry/ReadEntry returns | 
| 249 // ERR_IO_PENDING, and the callback should not return that value either. | 270 // ERR_IO_PENDING, and the callback should not return that value either. | 
| 250 LOG(ERROR) | 271 LOG(ERROR) | 
| 251 << "Failed to complete write to PNaCl Translation Cache Entry: " | 272 << "Failed to complete write to PNaCl Translation Cache Entry: " | 
| 252 << rv; | 273 << rv; | 
| 253 step_ = CLOSE_ENTRY; | 274 step_ = CLOSE_ENTRY; | 
| 254 CloseEntry(rv); | 275 CloseEntry(rv); | 
| 255 break; | 276 break; | 
| 256 } else if (rv > 0) { | 277 } else if (rv > 0) { | 
| 257 // For reads, copy the data that was just returned | 278 io_buf_->DidConsume(rv); | 
| 258 if (is_read_) | 279 if (io_buf_->BytesRemaining() > 0) { | 
| 259 read_nexe_->append(read_buf_->data(), rv); | 280 is_read_ | 
| 260 bytes_transferred_ += rv; | 281 ? ReadEntry(io_buf_->BytesConsumed(), io_buf_->BytesRemaining()) | 
| 261 if (bytes_transferred_ < bytes_to_transfer_) { | 282 : WriteEntry(io_buf_->BytesConsumed(), io_buf_->BytesRemaining()); | 
| 262 int len = bytes_to_transfer_ - bytes_transferred_; | |
| 263 is_read_ ? ReadEntry(bytes_transferred_, len) | |
| 264 : WriteEntry(bytes_transferred_, len); | |
| 265 break; | 283 break; | 
| 266 } | 284 } | 
| 267 } | 285 } | 
| 268 // rv == 0 or we fell through (i.e. we have transferred all the bytes) | 286 // rv == 0 or we fell through (i.e. we have transferred all the bytes) | 
| 269 step_ = CLOSE_ENTRY; | 287 step_ = CLOSE_ENTRY; | 
| 288 DCHECK(io_buf_->BytesConsumed() == io_buf_->size()); | |
| 289 if (is_read_) | |
| 290 io_buf_->SetOffset(0); | |
| 270 CloseEntry(0); | 291 CloseEntry(0); | 
| 271 break; | 292 break; | 
| 272 | 293 | 
| 273 case CLOSE_ENTRY: | 294 case CLOSE_ENTRY: | 
| 274 step_ = UNINITIALIZED; | 295 step_ = UNINITIALIZED; | 
| 275 break; | 296 break; | 
| 276 } | 297 } | 
| 277 } | 298 } | 
| 278 | 299 | 
| 279 ////////////////////////////////////////////////////////////////////// | 300 ////////////////////////////////////////////////////////////////////// | 
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 327 if (!init_callback_.is_null()) { | 348 if (!init_callback_.is_null()) { | 
| 328 init_callback_.Run(rv); | 349 init_callback_.Run(rv); | 
| 329 init_callback_.Reset(); | 350 init_callback_.Reset(); | 
| 330 } | 351 } | 
| 331 } | 352 } | 
| 332 | 353 | 
| 333 ////////////////////////////////////////////////////////////////////// | 354 ////////////////////////////////////////////////////////////////////// | 
| 334 // High-level API | 355 // High-level API | 
| 335 | 356 | 
| 336 void PnaclTranslationCache::StoreNexe(const std::string& key, | 357 void PnaclTranslationCache::StoreNexe(const std::string& key, | 
| 337 const std::string& nexe) { | 358 net::DrainableIOBuffer* nexe_data) { | 
| 338 StoreNexe(key, nexe, CompletionCallback()); | 359 StoreNexe(key, nexe_data, CompletionCallback()); | 
| 
 
jvoung (off chromium)
2013/07/30 22:51:39
Does this version of StoreNexe need to remain?
 
Derek Schuff
2013/07/31 00:04:16
This is the one my current version of the code act
 
 | |
| 339 } | 360 } | 
| 340 | 361 | 
| 341 void PnaclTranslationCache::StoreNexe(const std::string& key, | 362 void PnaclTranslationCache::StoreNexe(const std::string& key, | 
| 342 const std::string& nexe, | 363 net::DrainableIOBuffer* nexe_data, | 
| 343 const CompletionCallback& callback) { | 364 const CompletionCallback& callback) { | 
| 344 PnaclTranslationCacheEntry* entry = new PnaclTranslationCacheEntry( | 365 PnaclTranslationCacheEntry* entry = PnaclTranslationCacheEntry::GetWriteEntry( | 
| 345 AsWeakPtr(), key, NULL, nexe, callback, false); | 366 AsWeakPtr(), key, nexe_data, callback); | 
| 346 open_entries_[entry] = entry; | 367 open_entries_[entry] = entry; | 
| 347 entry->Start(); | 368 entry->Start(); | 
| 348 } | 369 } | 
| 349 | 370 | 
| 350 void PnaclTranslationCache::GetNexe(const std::string& key, | 371 void PnaclTranslationCache::GetNexe(const std::string& key, | 
| 351 std::string* nexe, | 372 const NexeCallback& callback) { | 
| 352 const CompletionCallback& callback) { | 373 PnaclTranslationCacheEntry* entry = | 
| 353 PnaclTranslationCacheEntry* entry = new PnaclTranslationCacheEntry( | 374 PnaclTranslationCacheEntry::GetReadEntry(AsWeakPtr(), key, callback); | 
| 354 AsWeakPtr(), key, nexe, std::string(), callback, true); | |
| 355 open_entries_[entry] = entry; | 375 open_entries_[entry] = entry; | 
| 356 entry->Start(); | 376 entry->Start(); | 
| 357 } | 377 } | 
| 358 | 378 | 
| 359 int PnaclTranslationCache::InitCache(const base::FilePath& cache_directory, | 379 int PnaclTranslationCache::InitCache(const base::FilePath& cache_directory, | 
| 360 bool in_memory, | 380 bool in_memory, | 
| 361 const CompletionCallback& callback) { | 381 const CompletionCallback& callback) { | 
| 362 int rv; | 382 int rv; | 
| 363 in_memory_ = in_memory; | 383 in_memory_ = in_memory; | 
| 364 if (in_memory_) { | 384 if (in_memory_) { | 
| 365 rv = InitWithMemBackend(kMaxMemCacheSize, callback); | 385 rv = InitWithMemBackend(kMaxMemCacheSize, callback); | 
| 366 } else { | 386 } else { | 
| 367 rv = InitWithDiskBackend(cache_directory, | 387 rv = InitWithDiskBackend(cache_directory, kMaxDiskCacheSize, callback); | 
| 368 kMaxDiskCacheSize, | |
| 369 callback); | |
| 370 } | 388 } | 
| 371 | 389 | 
| 372 return rv; | 390 return rv; | 
| 373 } | 391 } | 
| 374 | 392 | 
| 375 int PnaclTranslationCache::Size() { | 393 int PnaclTranslationCache::Size() { | 
| 376 if (!disk_cache_) | 394 if (!disk_cache_) | 
| 377 return -1; | 395 return -1; | 
| 378 return disk_cache_->GetEntryCount(); | 396 return disk_cache_->GetEntryCount(); | 
| 379 } | 397 } | 
| 380 | 398 | 
| 399 // static | |
| 400 std::string PnaclTranslationCache::GetKey(const nacl::PnaclCacheInfo& info) { | |
| 401 if (!info.pexe_url.is_valid() || info.abi_version < 0 || info.opt_level < 0) | |
| 402 return std::string(); | |
| 403 // Filter the username, password, and ref components from the URL | |
| 404 GURL::Replacements replacements; | |
| 405 replacements.ClearUsername(); | |
| 406 replacements.ClearPassword(); | |
| 407 replacements.ClearRef(); | |
| 408 GURL key_url(info.pexe_url.ReplaceComponents(replacements)); | |
| 409 std::string retval(key_url.spec()); | |
| 410 retval += ";" + IntToString(info.abi_version) + ";" + | |
| 
 
jvoung (off chromium)
2013/07/30 22:51:39
Could label the fields, so that it's easier to tel
 
Derek Schuff
2013/07/31 00:04:16
Done.
 
 | |
| 411 IntToString(info.opt_level) + ";"; | |
| 412 // You would think that there is already code to format base::Time values | |
| 413 // somewhere, but I haven't found it yet. In any case, doing it ourselves | |
| 414 // here means we can keep the format stable. | |
| 
 
jvoung (off chromium)
2013/07/30 22:51:39
There's strftime, but then you'd have to convert t
 
Derek Schuff
2013/07/31 00:04:16
Yeah in the end I decided it's just as well that w
 
 | |
| 415 base::Time::Exploded exploded; | |
| 416 info.last_modified.UTCExplode(&exploded); | |
| 417 retval += IntToString(exploded.year) + ":" + IntToString(exploded.month) + | |
| 418 ":" + IntToString(exploded.day_of_month) + ":" + | |
| 419 IntToString(exploded.hour) + ":" + IntToString(exploded.minute) + | |
| 420 ":" + IntToString(exploded.second) + ":" + | |
| 421 IntToString(exploded.millisecond) + ";"; | |
| 
 
jvoung (off chromium)
2013/07/30 22:51:39
Could label the time UTC.
 
Derek Schuff
2013/07/31 00:04:16
Done.
 
 | |
| 422 retval += info.etag; | |
| 423 return retval; | |
| 424 } | |
| 381 } // namespace pnacl | 425 } // namespace pnacl | 
| OLD | NEW |