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

Unified Diff: net/base/sdch_dictionary_fetcher.cc

Issue 495523003: Change SDCHDictionaryFetcher to use URLRequest instead of URLFetcher. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Some more comment tweaking. Created 6 years, 3 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: net/base/sdch_dictionary_fetcher.cc
diff --git a/net/base/sdch_dictionary_fetcher.cc b/net/base/sdch_dictionary_fetcher.cc
index a765dc3a836d6943b49131a2a387f956dbfb5e24..13e64abe8c5d3a87f1d924b2b4618d41dc9340f2 100644
--- a/net/base/sdch_dictionary_fetcher.cc
+++ b/net/base/sdch_dictionary_fetcher.cc
@@ -4,25 +4,36 @@
#include "net/base/sdch_dictionary_fetcher.h"
+#include <stdint.h>
+
+#include "base/auto_reset.h"
#include "base/bind.h"
#include "base/compiler_specific.h"
-#include "base/message_loop/message_loop.h"
+#include "base/thread_task_runner_handle.h"
#include "net/base/load_flags.h"
-#include "net/url_request/url_fetcher.h"
-#include "net/url_request/url_request_context_getter.h"
+#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_status.h"
+#include "net/url_request/url_request_throttler_manager.h"
+
+namespace {
+
+const int kBufferSize = 4096;
+
+} // namespace
namespace net {
SdchDictionaryFetcher::SdchDictionaryFetcher(
SdchManager* manager,
- scoped_refptr<URLRequestContextGetter> context)
- : manager_(manager),
- task_is_pending_(false),
+ URLRequestContext* context)
+ : next_state_(STATE_NONE),
+ in_loop_(false),
+ manager_(manager),
context_(context),
weak_factory_(this) {
DCHECK(CalledOnValidThread());
DCHECK(manager);
+ DCHECK(context);
}
SdchDictionaryFetcher::~SdchDictionaryFetcher() {
@@ -47,59 +58,178 @@ void SdchDictionaryFetcher::Schedule(const GURL& dictionary_url) {
}
attempted_load_.insert(dictionary_url);
fetch_queue_.push(dictionary_url);
- ScheduleDelayedRun();
+
+ next_state_ = STATE_IDLE;
+
+ // There are no callbacks to user code from the dictionary fetcher,
+ // and Schedule() is only called from user code, so this call to DoLoop()
+ // does not require an |if (in_loop_) return;| guard.
+ DoLoop(OK);
}
void SdchDictionaryFetcher::Cancel() {
DCHECK(CalledOnValidThread());
+ next_state_ = STATE_NONE;
+
while (!fetch_queue_.empty())
fetch_queue_.pop();
attempted_load_.clear();
weak_factory_.InvalidateWeakPtrs();
- current_fetch_.reset(NULL);
+ current_request_.reset(NULL);
+ buffer_ = NULL;
+ dictionary_.clear();
}
-void SdchDictionaryFetcher::ScheduleDelayedRun() {
- if (fetch_queue_.empty() || current_fetch_.get() || task_is_pending_)
+void SdchDictionaryFetcher::OnResponseStarted(URLRequest* request) {
+ DCHECK(CalledOnValidThread());
+ DCHECK_EQ(request, current_request_.get());
+ DCHECK_EQ(next_state_, STATE_REQUEST_STARTED);
+
+ // The response has started, so the stream can be read from.
+ next_state_ = STATE_REQUEST_READING;
+
+ // If this function was synchronously called, the containing
+ // state machine loop will handle the state transition. Otherwise,
Ryan Sleevi 2014/09/04 20:06:20 here
Randy Smith (Not in Mondays) 2014/09/07 14:09:38 Done.
+ // restart the state machine loop.
+ if (in_loop_)
return;
- base::MessageLoop::current()->PostDelayedTask(FROM_HERE,
- base::Bind(&SdchDictionaryFetcher::StartFetching,
- weak_factory_.GetWeakPtr()),
- base::TimeDelta::FromMilliseconds(kMsDelayFromRequestTillDownload));
- task_is_pending_ = true;
+
+ DoLoop(request->status().error());
}
-void SdchDictionaryFetcher::StartFetching() {
+void SdchDictionaryFetcher::OnReadCompleted(URLRequest* request,
+ int bytes_read) {
DCHECK(CalledOnValidThread());
- DCHECK(task_is_pending_);
- task_is_pending_ = false;
+ DCHECK_EQ(request, current_request_.get());
+ DCHECK_EQ(next_state_, STATE_REQUEST_READING);
+
+ // No state transition is required in this function; the
+ // completion of the request is detected in DoRead().
- // Handle losing the race against Cancel().
- if (fetch_queue_.empty())
+ if (request->status().is_success())
+ dictionary_.append(buffer_->data(), bytes_read);
+
+ // If this function was synchronously called, the containing
+ // state machine loop will handle the state transition. Otherwise,
Ryan Sleevi 2014/09/04 20:06:20 here
Randy Smith (Not in Mondays) 2014/09/07 14:09:38 Done.
+ // restart the state machine loop.
+ if (in_loop_)
return;
- DCHECK(context_.get());
- current_fetch_.reset(URLFetcher::Create(
- fetch_queue_.front(), URLFetcher::GET, this));
+ DoLoop(request->status().error());
+}
+
+int SdchDictionaryFetcher::DoLoop(int rv) {
+ DCHECK(!in_loop_);
+ base::AutoReset<bool> auto_reset_in_loop(&in_loop_, true);
+
+ do {
+ State state = next_state_;
+ next_state_ = STATE_NONE;
+ switch (state) {
+ case STATE_IDLE:
+ rv = DoDispatchRequest(rv);
+ break;
+ case STATE_REQUEST_STARTED:
+ rv = DoRequestStarted(rv);
+ break;
+ case STATE_REQUEST_READING:
+ rv = DoRead(rv);
+ break;
+ case STATE_REQUEST_COMPLETE:
+ rv = DoCompleteRequest(rv);
+ break;
+ case STATE_NONE:
+ NOTREACHED();
+ }
+ } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE);
+
+ return rv;
+}
+
+int SdchDictionaryFetcher::DoDispatchRequest(int rv) {
+ DCHECK(CalledOnValidThread());
+
+ // |rv| is ignored, as the result from the previous request doesn't
+ // affect the next request.
+
+ if (fetch_queue_.empty() || current_request_.get()) {
+ next_state_ = STATE_NONE;
+ return OK;
+ }
+
+ current_request_ = context_->CreateRequest(
+ fetch_queue_.front(), IDLE, this, NULL);
+ current_request_->SetLoadFlags(LOAD_DO_NOT_SEND_COOKIES |
+ LOAD_DO_NOT_SAVE_COOKIES);
+ buffer_ = new IOBuffer(kBufferSize);
fetch_queue_.pop();
- current_fetch_->SetRequestContext(context_.get());
- current_fetch_->SetLoadFlags(LOAD_DO_NOT_SEND_COOKIES |
- LOAD_DO_NOT_SAVE_COOKIES);
- current_fetch_->Start();
+
+ next_state_ = STATE_REQUEST_STARTED;
+ current_request_->Start();
+
+ return OK;
}
-void SdchDictionaryFetcher::OnURLFetchComplete(
- const URLFetcher* source) {
+int SdchDictionaryFetcher::DoRequestStarted(int rv) {
DCHECK(CalledOnValidThread());
- if ((200 == source->GetResponseCode()) &&
- (source->GetStatus().status() == URLRequestStatus::SUCCESS)) {
- std::string data;
- source->GetResponseAsString(&data);
- manager_->AddSdchDictionary(data, source->GetURL());
+ DCHECK_EQ(rv, OK); // Can only come straight from above function.
+
+ // The transition to STATE_REQUEST_READING occurs in the
+ // OnResponseStarted() callback triggered by URLRequest::Start()
+ // (called in DoDispatchRequest(), above). If that callback did not
Ryan Sleevi 2014/09/04 20:06:20 here
Randy Smith (Not in Mondays) 2014/09/07 14:09:39 Done.
+ // occur synchronously, this routine is executed; it returns ERR_IO_PENDING,
+ // indicating to the controlling loop that no further work should be done
+ // until the callback occurs (which will re-invoke DoLoop()).
+ next_state_ = STATE_REQUEST_STARTED;
+ return ERR_IO_PENDING;
+}
+
+int SdchDictionaryFetcher::DoRead(int rv) {
+ DCHECK(CalledOnValidThread());
+
+ // If there's been an error, abort the current request.
+ if (rv != OK) {
+ current_request_.reset();
+ buffer_ = NULL;
+ next_state_ = STATE_IDLE;
+
+ return OK;
+ }
+
+ next_state_ = STATE_REQUEST_READING;
+ int bytes_read = 0;
+ if (!current_request_->Read(buffer_.get(), kBufferSize, &bytes_read)) {
+ if (current_request_->status().is_io_pending())
+ return ERR_IO_PENDING;
+
+ DCHECK_NE(current_request_->status().error(), OK);
+
+ return current_request_->status().error();
}
- current_fetch_.reset(NULL);
- ScheduleDelayedRun();
+
+ if (bytes_read != 0)
+ dictionary_.append(buffer_->data(), bytes_read);
+ else
+ next_state_ = STATE_REQUEST_COMPLETE;
+
+ return OK;
+}
+
+int SdchDictionaryFetcher::DoCompleteRequest(int rv) {
+ DCHECK(CalledOnValidThread());
+
+ // If the dictionary was successfully fetched, add it to the manager.
+ if (rv == OK)
+ manager_->AddSdchDictionary(dictionary_, current_request_->url());
+
+ current_request_.reset();
+ buffer_ = NULL;
+ dictionary_.clear();
+
+ next_state_ = STATE_IDLE;
+
+ return OK;
}
} // namespace net

Powered by Google App Engine
This is Rietveld 408576698