Chromium Code Reviews| Index: content/browser/service_worker/service_worker_storage.cc |
| diff --git a/content/browser/service_worker/service_worker_storage.cc b/content/browser/service_worker/service_worker_storage.cc |
| index 13e0ca311b141d7124ef2c95f137d5331b6e0ea0..f09d614e55ee5c90e5e6e93af8b867348c172514 100644 |
| --- a/content/browser/service_worker/service_worker_storage.cc |
| +++ b/content/browser/service_worker/service_worker_storage.cc |
| @@ -20,6 +20,7 @@ |
| #include "content/browser/service_worker/service_worker_version.h" |
| #include "content/common/service_worker/service_worker_types.h" |
| #include "content/public/browser/browser_thread.h" |
| +#include "net/base/io_buffer.h" |
| #include "net/base/net_errors.h" |
| #include "webkit/browser/quota/quota_manager_proxy.h" |
| @@ -73,6 +74,130 @@ ServiceWorkerStatusCode DatabaseStatusToStatusCode( |
| } |
| } |
| +class CompareHelper : public base::RefCounted<CompareHelper> { |
|
falken
2014/07/17 06:33:42
would ResponseComparer be a more descriptive name?
michaeln
2014/07/18 03:40:49
Done (classname but not comment since the name ind
|
| + public: |
| + CompareHelper( |
| + base::WeakPtr<ServiceWorkerStorage> owner, |
| + scoped_ptr<ServiceWorkerResponseReader> lhs, |
| + scoped_ptr<ServiceWorkerResponseReader> rhs, |
| + const ServiceWorkerStorage::CompareCallback& callback) |
| + : owner_(owner), |
| + completion_callback_(callback), |
| + lhs_reader_(lhs.release()), |
| + rhs_reader_(rhs.release()), |
| + completion_count_(0), |
| + previous_result_(0) { |
| + } |
| + |
| + void Start(); |
| + |
| + private: |
| + friend class base::RefCounted<CompareHelper>; |
| + |
| + static const int kBufferSize = 16 * 1024; |
| + |
| + ~CompareHelper() {} |
| + void ReadInfos(); |
| + void OnReadInfoComplete(int result); |
| + void ReadSomeData(); |
| + void OnReadDataComplete(int result); |
| + |
| + base::WeakPtr<ServiceWorkerStorage> owner_; |
| + ServiceWorkerStorage::CompareCallback completion_callback_; |
| + scoped_ptr<ServiceWorkerResponseReader> lhs_reader_; |
| + scoped_refptr<HttpResponseInfoIOBuffer> lhs_info_; |
| + scoped_refptr<net::IOBuffer> lhs_buffer_; |
| + scoped_ptr<ServiceWorkerResponseReader> rhs_reader_; |
| + scoped_refptr<HttpResponseInfoIOBuffer> rhs_info_; |
| + scoped_refptr<net::IOBuffer> rhs_buffer_; |
| + int completion_count_; |
| + int previous_result_; |
| + DISALLOW_COPY_AND_ASSIGN(CompareHelper); |
| +}; |
| + |
| +void CompareHelper::Start() { |
| + lhs_buffer_ = new net::IOBuffer(kBufferSize); |
| + lhs_info_ = new HttpResponseInfoIOBuffer(); |
| + rhs_buffer_ = new net::IOBuffer(kBufferSize); |
| + rhs_info_ = new HttpResponseInfoIOBuffer(); |
| + |
| + ReadInfos(); |
| +} |
| + |
| +void CompareHelper::ReadInfos() { |
| + lhs_reader_->ReadInfo( |
| + lhs_info_, |
| + base::Bind(&CompareHelper::OnReadInfoComplete, |
| + this)); |
| + rhs_reader_->ReadInfo( |
| + rhs_info_, |
| + base::Bind(&CompareHelper::OnReadInfoComplete, |
| + this)); |
| +} |
| + |
| +void CompareHelper::OnReadInfoComplete(int result) { |
| + if (completion_callback_.is_null() || !owner_) |
| + return; |
| + if (result < 0) { |
| + completion_callback_.Run(SERVICE_WORKER_ERROR_FAILED, -1); |
| + completion_callback_.Reset(); |
| + return; |
| + } |
| + if (++(completion_count_) != 2) |
|
falken
2014/07/17 06:33:42
nit: those parens look unnecessary to me
michaeln
2014/07/18 03:40:49
Done.
|
| + return; |
| + |
| + if (lhs_info_->response_data_size != rhs_info_->response_data_size) { |
| + completion_callback_.Run(SERVICE_WORKER_OK, -1); |
|
falken
2014/07/17 06:33:42
nit: this seems another reason that "bool equals"
michaeln
2014/07/18 03:40:49
Done.
|
| + return; |
| + } |
| + ReadSomeData(); |
| +} |
| + |
| +void CompareHelper::ReadSomeData() { |
| + completion_count_ = 0; |
| + lhs_reader_->ReadData( |
| + lhs_buffer_, |
| + kBufferSize, |
| + base::Bind(&CompareHelper::OnReadDataComplete, this)); |
| + rhs_reader_->ReadData( |
| + rhs_buffer_, |
| + kBufferSize, |
| + base::Bind(&CompareHelper::OnReadDataComplete, this)); |
| +} |
| + |
| +void CompareHelper::OnReadDataComplete(int result) { |
| + if (completion_callback_.is_null() || !owner_) |
| + return; |
| + if (result < 0) { |
| + completion_callback_.Run(SERVICE_WORKER_ERROR_FAILED, -1); |
| + completion_callback_.Reset(); |
| + return; |
| + } |
| + if (++(completion_count_) != 2) { |
|
falken
2014/07/17 06:33:42
nit: i prefer removing those parens
michaeln
2014/07/18 03:40:48
Done.
|
| + previous_result_ = result; |
| + return; |
| + } |
| + |
| + if (result != previous_result_) { |
|
falken
2014/07/17 06:33:42
I was confused at first. I see that lhs and rhs mu
michaeln
2014/07/18 03:40:49
Good questin, I'm not sure if it's guaranteed to a
|
| + completion_callback_.Run(SERVICE_WORKER_ERROR_FAILED, -1); |
| + return; |
| + } |
| + |
| + if (result == 0) { |
| + completion_callback_.Run(SERVICE_WORKER_OK, 0); |
| + return; |
| + } |
| + |
| + int compare_result = |
| + memcmp(lhs_buffer_->data(), rhs_buffer_->data(), result); |
| + if (compare_result != 0) { |
| + completion_callback_.Run(SERVICE_WORKER_OK, compare_result); |
| + return; |
| + } |
| + |
| + ReadSomeData(); |
| +} |
| + |
| } // namespace |
| ServiceWorkerStorage::InitialData::InitialData() |
| @@ -392,6 +517,18 @@ void ServiceWorkerStorage::DoomUncommittedResponse(int64 id) { |
| StartPurgingResources(std::vector<int64>(1, id)); |
| } |
| +void ServiceWorkerStorage::CompareScriptResources( |
| + int64 lhs_id, int64 rhs_id, |
| + const CompareCallback& callback) { |
| + DCHECK(!callback.is_null()); |
| + scoped_refptr<CompareHelper> helper = |
| + new CompareHelper(weak_factory_.GetWeakPtr(), |
| + CreateResponseReader(lhs_id), |
| + CreateResponseReader(rhs_id), |
| + callback); |
| + helper->Start(); // It deletes itself when done. |
| +} |
| + |
| void ServiceWorkerStorage::DeleteAndStartOver(const StatusCallback& callback) { |
| Disable(); |
| @@ -761,16 +898,19 @@ ServiceWorkerStorage::GetOrCreateRegistration( |
| version->SetStatus(data.is_active ? |
| ServiceWorkerVersion::ACTIVATED : ServiceWorkerVersion::INSTALLED); |
| version->script_cache_map()->SetResources(resources); |
| + |
| + // TODO(michaeln): need to activate a waiting version that wasn't |
| + // actrivated in an earlier session, maybe test for this condition |
| + // (waitingversion and no activeversion) when navigating to a page? |
| } |
| - if (version->status() == ServiceWorkerVersion::ACTIVATED) |
| + if (version->status() == ServiceWorkerVersion::ACTIVATED) { |
| registration->SetActiveVersion(version); |
| - else if (version->status() == ServiceWorkerVersion::INSTALLED) |
| + } else if (version->status() == ServiceWorkerVersion::INSTALLED) { |
| registration->SetWaitingVersion(version); |
| - else |
| + } else { |
| NOTREACHED(); |
| - // TODO(michaeln): Hmmm, what if DeleteReg was invoked after |
| - // the Find result we're returning here? NOTREACHED condition? |
| + } |
|
falken
2014/07/17 06:33:42
nit: these braces aren't neeeded
michaeln
2014/07/18 03:40:49
Done.
|
| return registration; |
| } |