| 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 ac8e3322de251e1a528a9f595ed7e3109754728d..ab73931ce614b32d33342a396969431d57f1555a 100644
|
| --- a/content/browser/service_worker/service_worker_storage.cc
|
| +++ b/content/browser/service_worker/service_worker_storage.cc
|
| @@ -21,6 +21,7 @@
|
| #include "content/common/service_worker/service_worker_types.h"
|
| #include "content/public/browser/browser_thread.h"
|
| #include "net/base/completion_callback.h"
|
| +#include "net/base/io_buffer.h"
|
| #include "net/base/net_errors.h"
|
| #include "webkit/browser/quota/quota_manager_proxy.h"
|
|
|
| @@ -72,6 +73,133 @@ ServiceWorkerStatusCode DatabaseStatusToStatusCode(
|
| }
|
| }
|
|
|
| +class ResponseComparer : public base::RefCounted<ResponseComparer> {
|
| + public:
|
| + ResponseComparer(
|
| + 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<ResponseComparer>;
|
| +
|
| + static const int kBufferSize = 16 * 1024;
|
| +
|
| + ~ResponseComparer() {}
|
| + 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(ResponseComparer);
|
| +};
|
| +
|
| +void ResponseComparer::Start() {
|
| + lhs_buffer_ = new net::IOBuffer(kBufferSize);
|
| + lhs_info_ = new HttpResponseInfoIOBuffer();
|
| + rhs_buffer_ = new net::IOBuffer(kBufferSize);
|
| + rhs_info_ = new HttpResponseInfoIOBuffer();
|
| +
|
| + ReadInfos();
|
| +}
|
| +
|
| +void ResponseComparer::ReadInfos() {
|
| + lhs_reader_->ReadInfo(
|
| + lhs_info_,
|
| + base::Bind(&ResponseComparer::OnReadInfoComplete,
|
| + this));
|
| + rhs_reader_->ReadInfo(
|
| + rhs_info_,
|
| + base::Bind(&ResponseComparer::OnReadInfoComplete,
|
| + this));
|
| +}
|
| +
|
| +void ResponseComparer::OnReadInfoComplete(int result) {
|
| + if (completion_callback_.is_null() || !owner_)
|
| + return;
|
| + if (result < 0) {
|
| + completion_callback_.Run(SERVICE_WORKER_ERROR_FAILED, false);
|
| + completion_callback_.Reset();
|
| + return;
|
| + }
|
| + if (++completion_count_ != 2)
|
| + return;
|
| +
|
| + if (lhs_info_->response_data_size != rhs_info_->response_data_size) {
|
| + completion_callback_.Run(SERVICE_WORKER_OK, false);
|
| + return;
|
| + }
|
| + ReadSomeData();
|
| +}
|
| +
|
| +void ResponseComparer::ReadSomeData() {
|
| + completion_count_ = 0;
|
| + lhs_reader_->ReadData(
|
| + lhs_buffer_,
|
| + kBufferSize,
|
| + base::Bind(&ResponseComparer::OnReadDataComplete, this));
|
| + rhs_reader_->ReadData(
|
| + rhs_buffer_,
|
| + kBufferSize,
|
| + base::Bind(&ResponseComparer::OnReadDataComplete, this));
|
| +}
|
| +
|
| +void ResponseComparer::OnReadDataComplete(int result) {
|
| + if (completion_callback_.is_null() || !owner_)
|
| + return;
|
| + if (result < 0) {
|
| + completion_callback_.Run(SERVICE_WORKER_ERROR_FAILED, false);
|
| + completion_callback_.Reset();
|
| + return;
|
| + }
|
| + if (++completion_count_ != 2) {
|
| + previous_result_ = result;
|
| + return;
|
| + }
|
| +
|
| + // TODO(michaeln): Probably shouldn't assume that the amounts read from
|
| + // each reader will always be the same. This would wrongly signal false
|
| + // in that case.
|
| + if (result != previous_result_) {
|
| + completion_callback_.Run(SERVICE_WORKER_OK, false);
|
| + return;
|
| + }
|
| +
|
| + if (result == 0) {
|
| + completion_callback_.Run(SERVICE_WORKER_OK, true);
|
| + return;
|
| + }
|
| +
|
| + int compare_result =
|
| + memcmp(lhs_buffer_->data(), rhs_buffer_->data(), result);
|
| + if (compare_result != 0) {
|
| + completion_callback_.Run(SERVICE_WORKER_OK, false);
|
| + return;
|
| + }
|
| +
|
| + ReadSomeData();
|
| +}
|
| +
|
| } // namespace
|
|
|
| ServiceWorkerStorage::InitialData::InitialData()
|
| @@ -391,6 +519,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<ResponseComparer> comparer =
|
| + new ResponseComparer(weak_factory_.GetWeakPtr(),
|
| + CreateResponseReader(lhs_id),
|
| + CreateResponseReader(rhs_id),
|
| + callback);
|
| + comparer->Start(); // It deletes itself when done.
|
| +}
|
| +
|
| void ServiceWorkerStorage::DeleteAndStartOver(const StatusCallback& callback) {
|
| Disable();
|
|
|
| @@ -760,6 +900,10 @@ 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)
|
| @@ -768,8 +912,7 @@ ServiceWorkerStorage::GetOrCreateRegistration(
|
| registration->SetWaitingVersion(version);
|
| else
|
| NOTREACHED();
|
| - // TODO(michaeln): Hmmm, what if DeleteReg was invoked after
|
| - // the Find result we're returning here? NOTREACHED condition?
|
| +
|
| return registration;
|
| }
|
|
|
|
|