Commit be3c72f8 authored by xunjieli's avatar xunjieli Committed by Commit bot

Make URLRequestContextAdapter initialization asynchronous

Currently we place a 2-second on URLRequestContextAdapter initialization, so
that context can be initialized when embedders make requests. This CL changes
so that tasks that depend on context being initialized will be run after the
context is initialized properly, and URLRequestContextAdapter initialization
won't block.

BUG=

Review URL: https://codereview.chromium.org/617393005

Cr-Commit-Position: refs/heads/master@{#299145}
parent c4d8a6fb
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
package org.chromium.net; package org.chromium.net;
import android.content.Context; import android.content.Context;
import android.os.ConditionVariable;
import android.os.Process; import android.os.Process;
import android.util.Log; import android.util.Log;
...@@ -27,8 +26,6 @@ public class ChromiumUrlRequestContext { ...@@ -27,8 +26,6 @@ public class ChromiumUrlRequestContext {
*/ */
private long mChromiumUrlRequestContextAdapter; private long mChromiumUrlRequestContextAdapter;
private final ConditionVariable mStarted = new ConditionVariable();
/** /**
* Constructor. * Constructor.
* *
...@@ -37,11 +34,9 @@ public class ChromiumUrlRequestContext { ...@@ -37,11 +34,9 @@ public class ChromiumUrlRequestContext {
String config) { String config) {
mChromiumUrlRequestContextAdapter = nativeCreateRequestContextAdapter( mChromiumUrlRequestContextAdapter = nativeCreateRequestContextAdapter(
context, userAgent, getLoggingLevel(), config); context, userAgent, getLoggingLevel(), config);
if (mChromiumUrlRequestContextAdapter == 0) if (mChromiumUrlRequestContextAdapter == 0) {
throw new NullPointerException("Context Adapter creation failed"); throw new NullPointerException("Context Adapter creation failed");
}
// TODO(mef): Revisit the need of block here.
mStarted.block(2000);
} }
/** /**
...@@ -90,7 +85,6 @@ public class ChromiumUrlRequestContext { ...@@ -90,7 +85,6 @@ public class ChromiumUrlRequestContext {
private void initNetworkThread() { private void initNetworkThread() {
Thread.currentThread().setName("ChromiumNet"); Thread.currentThread().setName("ChromiumNet");
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
mStarted.open();
} }
@Override @Override
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/location.h" #include "base/location.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_number_conversions.h" #include "base/strings/string_number_conversions.h"
#include "components/cronet/android/url_request_context_adapter.h" #include "components/cronet/android/url_request_context_adapter.h"
#include "components/cronet/android/wrapped_channel_upload_element_reader.h" #include "components/cronet/android/wrapped_channel_upload_element_reader.h"
...@@ -41,6 +42,7 @@ URLRequestAdapter::URLRequestAdapter(URLRequestContextAdapter* context, ...@@ -41,6 +42,7 @@ URLRequestAdapter::URLRequestAdapter(URLRequestContextAdapter* context,
} }
URLRequestAdapter::~URLRequestAdapter() { URLRequestAdapter::~URLRequestAdapter() {
DCHECK(OnNetworkThread());
CHECK(url_request_ == NULL); CHECK(url_request_ == NULL);
} }
...@@ -77,7 +79,7 @@ void URLRequestAdapter::AppendChunk(const char* bytes, int bytes_len, ...@@ -77,7 +79,7 @@ void URLRequestAdapter::AppendChunk(const char* bytes, int bytes_len,
VLOG(1) << "AppendChunk, len: " << bytes_len << ", last: " << is_last_chunk; VLOG(1) << "AppendChunk, len: " << bytes_len << ", last: " << is_last_chunk;
scoped_ptr<char[]> buf(new char[bytes_len]); scoped_ptr<char[]> buf(new char[bytes_len]);
memcpy(buf.get(), bytes, bytes_len); memcpy(buf.get(), bytes, bytes_len);
context_->GetNetworkTaskRunner()->PostTask( context_->PostTaskToNetworkThread(
FROM_HERE, FROM_HERE,
base::Bind(&URLRequestAdapter::OnAppendChunk, base::Bind(&URLRequestAdapter::OnAppendChunk,
base::Unretained(this), base::Unretained(this),
...@@ -108,7 +110,7 @@ std::string URLRequestAdapter::GetNegotiatedProtocol() const { ...@@ -108,7 +110,7 @@ std::string URLRequestAdapter::GetNegotiatedProtocol() const {
} }
void URLRequestAdapter::Start() { void URLRequestAdapter::Start() {
context_->GetNetworkTaskRunner()->PostTask( context_->PostTaskToNetworkThread(
FROM_HERE, FROM_HERE,
base::Bind(&URLRequestAdapter::OnInitiateConnection, base::Bind(&URLRequestAdapter::OnInitiateConnection,
base::Unretained(this))); base::Unretained(this)));
...@@ -116,10 +118,12 @@ void URLRequestAdapter::Start() { ...@@ -116,10 +118,12 @@ void URLRequestAdapter::Start() {
void URLRequestAdapter::OnAppendChunk(const scoped_ptr<char[]> bytes, void URLRequestAdapter::OnAppendChunk(const scoped_ptr<char[]> bytes,
int bytes_len, bool is_last_chunk) { int bytes_len, bool is_last_chunk) {
DCHECK(OnNetworkThread());
url_request_->AppendChunkToUpload(bytes.get(), bytes_len, is_last_chunk); url_request_->AppendChunkToUpload(bytes.get(), bytes_len, is_last_chunk);
} }
void URLRequestAdapter::OnInitiateConnection() { void URLRequestAdapter::OnInitiateConnection() {
DCHECK(OnNetworkThread());
if (canceled_) { if (canceled_) {
return; return;
} }
...@@ -159,12 +163,13 @@ void URLRequestAdapter::Cancel() { ...@@ -159,12 +163,13 @@ void URLRequestAdapter::Cancel() {
canceled_ = true; canceled_ = true;
context_->GetNetworkTaskRunner()->PostTask( context_->PostTaskToNetworkThread(
FROM_HERE, FROM_HERE,
base::Bind(&URLRequestAdapter::OnCancelRequest, base::Unretained(this))); base::Bind(&URLRequestAdapter::OnCancelRequest, base::Unretained(this)));
} }
void URLRequestAdapter::OnCancelRequest() { void URLRequestAdapter::OnCancelRequest() {
DCHECK(OnNetworkThread());
VLOG(1) << "Canceling chromium request: " << url_.possibly_invalid_spec(); VLOG(1) << "Canceling chromium request: " << url_.possibly_invalid_spec();
if (url_request_ != NULL) { if (url_request_ != NULL) {
...@@ -175,18 +180,21 @@ void URLRequestAdapter::OnCancelRequest() { ...@@ -175,18 +180,21 @@ void URLRequestAdapter::OnCancelRequest() {
} }
void URLRequestAdapter::Destroy() { void URLRequestAdapter::Destroy() {
context_->GetNetworkTaskRunner()->PostTask( context_->PostTaskToNetworkThread(
FROM_HERE, base::Bind(&URLRequestAdapter::OnDestroyRequest, this)); FROM_HERE, base::Bind(&URLRequestAdapter::OnDestroyRequest, this));
} }
// static // static
void URLRequestAdapter::OnDestroyRequest(URLRequestAdapter* self) { void URLRequestAdapter::OnDestroyRequest(URLRequestAdapter* self) {
DCHECK(self->OnNetworkThread());
VLOG(1) << "Destroying chromium request: " VLOG(1) << "Destroying chromium request: "
<< self->url_.possibly_invalid_spec(); << self->url_.possibly_invalid_spec();
delete self; delete self;
} }
// static
void URLRequestAdapter::OnResponseStarted(net::URLRequest* request) { void URLRequestAdapter::OnResponseStarted(net::URLRequest* request) {
DCHECK(OnNetworkThread());
if (request->status().status() != net::URLRequestStatus::SUCCESS) { if (request->status().status() != net::URLRequestStatus::SUCCESS) {
OnRequestFailed(); OnRequestFailed();
return; return;
...@@ -204,6 +212,7 @@ void URLRequestAdapter::OnResponseStarted(net::URLRequest* request) { ...@@ -204,6 +212,7 @@ void URLRequestAdapter::OnResponseStarted(net::URLRequest* request) {
// Reads all available data or starts an asynchronous read. // Reads all available data or starts an asynchronous read.
void URLRequestAdapter::Read() { void URLRequestAdapter::Read() {
DCHECK(OnNetworkThread());
while (true) { while (true) {
if (read_buffer_->RemainingCapacity() == 0) { if (read_buffer_->RemainingCapacity() == 0) {
int new_capacity = read_buffer_->capacity() + kBufferSizeIncrement; int new_capacity = read_buffer_->capacity() + kBufferSizeIncrement;
...@@ -241,6 +250,7 @@ void URLRequestAdapter::Read() { ...@@ -241,6 +250,7 @@ void URLRequestAdapter::Read() {
void URLRequestAdapter::OnReadCompleted(net::URLRequest* request, void URLRequestAdapter::OnReadCompleted(net::URLRequest* request,
int bytes_read) { int bytes_read) {
DCHECK(OnNetworkThread());
VLOG(1) << "Asynchronously read: " << bytes_read << " bytes"; VLOG(1) << "Asynchronously read: " << bytes_read << " bytes";
if (bytes_read < 0) { if (bytes_read < 0) {
OnRequestFailed(); OnRequestFailed();
...@@ -255,12 +265,14 @@ void URLRequestAdapter::OnReadCompleted(net::URLRequest* request, ...@@ -255,12 +265,14 @@ void URLRequestAdapter::OnReadCompleted(net::URLRequest* request,
} }
void URLRequestAdapter::OnBytesRead(int bytes_read) { void URLRequestAdapter::OnBytesRead(int bytes_read) {
DCHECK(OnNetworkThread());
read_buffer_->set_offset(read_buffer_->offset() + bytes_read); read_buffer_->set_offset(read_buffer_->offset() + bytes_read);
bytes_read_ += bytes_read; bytes_read_ += bytes_read;
total_bytes_read_ += bytes_read; total_bytes_read_ += bytes_read;
} }
void URLRequestAdapter::OnRequestSucceeded() { void URLRequestAdapter::OnRequestSucceeded() {
DCHECK(OnNetworkThread());
if (canceled_) { if (canceled_) {
return; return;
} }
...@@ -272,6 +284,7 @@ void URLRequestAdapter::OnRequestSucceeded() { ...@@ -272,6 +284,7 @@ void URLRequestAdapter::OnRequestSucceeded() {
} }
void URLRequestAdapter::OnRequestFailed() { void URLRequestAdapter::OnRequestFailed() {
DCHECK(OnNetworkThread());
if (canceled_) { if (canceled_) {
return; return;
} }
...@@ -283,10 +296,12 @@ void URLRequestAdapter::OnRequestFailed() { ...@@ -283,10 +296,12 @@ void URLRequestAdapter::OnRequestFailed() {
} }
void URLRequestAdapter::OnRequestCanceled() { void URLRequestAdapter::OnRequestCanceled() {
DCHECK(OnNetworkThread());
OnRequestCompleted(); OnRequestCompleted();
} }
void URLRequestAdapter::OnRequestCompleted() { void URLRequestAdapter::OnRequestCompleted() {
DCHECK(OnNetworkThread());
VLOG(1) << "Completed: " << url_.possibly_invalid_spec(); VLOG(1) << "Completed: " << url_.possibly_invalid_spec();
url_request_.reset(); url_request_.reset();
...@@ -295,7 +310,12 @@ void URLRequestAdapter::OnRequestCompleted() { ...@@ -295,7 +310,12 @@ void URLRequestAdapter::OnRequestCompleted() {
} }
unsigned char* URLRequestAdapter::Data() const { unsigned char* URLRequestAdapter::Data() const {
DCHECK(OnNetworkThread());
return reinterpret_cast<unsigned char*>(read_buffer_->StartOfBuffer()); return reinterpret_cast<unsigned char*>(read_buffer_->StartOfBuffer());
} }
bool URLRequestAdapter::OnNetworkThread() const {
return context_->GetNetworkTaskRunner()->BelongsToCurrentThread();
}
} // namespace cronet } // namespace cronet
...@@ -117,6 +117,8 @@ class URLRequestAdapter : public net::URLRequest::Delegate { ...@@ -117,6 +117,8 @@ class URLRequestAdapter : public net::URLRequest::Delegate {
virtual void OnReadCompleted(net::URLRequest* request, virtual void OnReadCompleted(net::URLRequest* request,
int bytes_read) override; int bytes_read) override;
bool OnNetworkThread() const;
private: private:
static void OnDestroyRequest(URLRequestAdapter* self); static void OnDestroyRequest(URLRequestAdapter* self);
......
...@@ -135,6 +135,7 @@ void URLRequestContextAdapter::Initialize( ...@@ -135,6 +135,7 @@ void URLRequestContextAdapter::Initialize(
void URLRequestContextAdapter::InitializeURLRequestContext( void URLRequestContextAdapter::InitializeURLRequestContext(
scoped_ptr<URLRequestContextConfig> config) { scoped_ptr<URLRequestContextConfig> config) {
DCHECK(GetNetworkTaskRunner()->BelongsToCurrentThread());
// TODO(mmenke): Add method to have the builder enable SPDY. // TODO(mmenke): Add method to have the builder enable SPDY.
net::URLRequestContextBuilder context_builder; net::URLRequestContextBuilder context_builder;
context_builder.set_network_delegate(new BasicNetworkDelegate()); context_builder.set_network_delegate(new BasicNetworkDelegate());
...@@ -178,6 +179,11 @@ void URLRequestContextAdapter::InitializeURLRequestContext( ...@@ -178,6 +179,11 @@ void URLRequestContextAdapter::InitializeURLRequestContext(
net::AlternateProtocol::QUIC, net::AlternateProtocol::QUIC,
1.0f); 1.0f);
} }
is_context_initialized_ = true;
while (!tasks_waiting_for_context_.empty()) {
tasks_waiting_for_context_.front().Run();
tasks_waiting_for_context_.pop();
}
} }
if (VLOG_IS_ON(2)) { if (VLOG_IS_ON(2)) {
...@@ -189,12 +195,34 @@ void URLRequestContextAdapter::InitializeURLRequestContext( ...@@ -189,12 +195,34 @@ void URLRequestContextAdapter::InitializeURLRequestContext(
delegate_->OnContextInitialized(this); delegate_->OnContextInitialized(this);
} }
void URLRequestContextAdapter::PostTaskToNetworkThread(
const tracked_objects::Location& posted_from,
const RunAfterContextInitTask& callback) {
GetNetworkTaskRunner()->PostTask(
posted_from,
base::Bind(
&URLRequestContextAdapter::RunTaskAfterContextInitOnNetworkThread,
this,
callback));
}
void URLRequestContextAdapter::RunTaskAfterContextInitOnNetworkThread(
const RunAfterContextInitTask& callback) {
DCHECK(GetNetworkTaskRunner()->BelongsToCurrentThread());
if (is_context_initialized_) {
callback.Run();
return;
}
tasks_waiting_for_context_.push(callback);
}
URLRequestContextAdapter::~URLRequestContextAdapter() { URLRequestContextAdapter::~URLRequestContextAdapter() {
DCHECK(GetNetworkTaskRunner()->BelongsToCurrentThread());
if (net_log_observer_) { if (net_log_observer_) {
context_->net_log()->RemoveThreadSafeObserver(net_log_observer_.get()); context_->net_log()->RemoveThreadSafeObserver(net_log_observer_.get());
net_log_observer_.reset(); net_log_observer_.reset();
} }
StopNetLog(); StopNetLogHelper();
// TODO(mef): Ensure that |network_thread_| is destroyed properly. // TODO(mef): Ensure that |network_thread_| is destroyed properly.
} }
...@@ -204,6 +232,7 @@ const std::string& URLRequestContextAdapter::GetUserAgent( ...@@ -204,6 +232,7 @@ const std::string& URLRequestContextAdapter::GetUserAgent(
} }
net::URLRequestContext* URLRequestContextAdapter::GetURLRequestContext() { net::URLRequestContext* URLRequestContextAdapter::GetURLRequestContext() {
DCHECK(GetNetworkTaskRunner()->BelongsToCurrentThread());
if (!context_) { if (!context_) {
LOG(ERROR) << "URLRequestContext is not set up"; LOG(ERROR) << "URLRequestContext is not set up";
} }
...@@ -216,6 +245,20 @@ URLRequestContextAdapter::GetNetworkTaskRunner() const { ...@@ -216,6 +245,20 @@ URLRequestContextAdapter::GetNetworkTaskRunner() const {
} }
void URLRequestContextAdapter::StartNetLogToFile(const std::string& file_name) { void URLRequestContextAdapter::StartNetLogToFile(const std::string& file_name) {
PostTaskToNetworkThread(
FROM_HERE,
base::Bind(
&URLRequestContextAdapter::StartNetLogToFileHelper, this, file_name));
}
void URLRequestContextAdapter::StopNetLog() {
PostTaskToNetworkThread(
FROM_HERE, base::Bind(&URLRequestContextAdapter::StopNetLogHelper, this));
}
void URLRequestContextAdapter::StartNetLogToFileHelper(
const std::string& file_name) {
DCHECK(GetNetworkTaskRunner()->BelongsToCurrentThread());
// Do nothing if already logging to a file. // Do nothing if already logging to a file.
if (net_log_logger_) if (net_log_logger_)
return; return;
...@@ -230,7 +273,8 @@ void URLRequestContextAdapter::StartNetLogToFile(const std::string& file_name) { ...@@ -230,7 +273,8 @@ void URLRequestContextAdapter::StartNetLogToFile(const std::string& file_name) {
net_log_logger_->StartObserving(context_->net_log()); net_log_logger_->StartObserving(context_->net_log());
} }
void URLRequestContextAdapter::StopNetLog() { void URLRequestContextAdapter::StopNetLogHelper() {
DCHECK(GetNetworkTaskRunner()->BelongsToCurrentThread());
if (net_log_logger_) { if (net_log_logger_) {
net_log_logger_->StopObserving(); net_log_logger_->StopObserving();
net_log_logger_.reset(); net_log_logger_.reset();
......
...@@ -5,9 +5,12 @@ ...@@ -5,9 +5,12 @@
#ifndef COMPONENTS_CRONET_ANDROID_URL_REQUEST_CONTEXT_ADAPTER_H_ #ifndef COMPONENTS_CRONET_ANDROID_URL_REQUEST_CONTEXT_ADAPTER_H_
#define COMPONENTS_CRONET_ANDROID_URL_REQUEST_CONTEXT_ADAPTER_H_ #define COMPONENTS_CRONET_ANDROID_URL_REQUEST_CONTEXT_ADAPTER_H_
#include <queue>
#include <string> #include <string>
#include "base/callback.h"
#include "base/compiler_specific.h" #include "base/compiler_specific.h"
#include "base/location.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
...@@ -24,6 +27,7 @@ class NetLogLogger; ...@@ -24,6 +27,7 @@ class NetLogLogger;
namespace cronet { namespace cronet {
struct URLRequestContextConfig; struct URLRequestContextConfig;
typedef base::Callback<void(void)> RunAfterContextInitTask;
// Implementation of the Chromium NetLog observer interface. // Implementation of the Chromium NetLog observer interface.
class NetLogObserver : public net::NetLog::ThreadSafeObserver { class NetLogObserver : public net::NetLog::ThreadSafeObserver {
...@@ -56,6 +60,16 @@ class URLRequestContextAdapter : public net::URLRequestContextGetter { ...@@ -56,6 +60,16 @@ class URLRequestContextAdapter : public net::URLRequestContextGetter {
std::string user_agent); std::string user_agent);
void Initialize(scoped_ptr<URLRequestContextConfig> config); void Initialize(scoped_ptr<URLRequestContextConfig> config);
// Posts a task that might depend on the context being initialized
// to the network thread.
void PostTaskToNetworkThread(const tracked_objects::Location& posted_from,
const RunAfterContextInitTask& callback);
// Runs a task that might depend on the context being initialized.
// This method should only be run on the network thread.
void RunTaskAfterContextInitOnNetworkThread(
const RunAfterContextInitTask& callback);
const std::string& GetUserAgent(const GURL& url) const; const std::string& GetUserAgent(const GURL& url) const;
// net::URLRequestContextGetter implementation: // net::URLRequestContextGetter implementation:
...@@ -75,11 +89,22 @@ class URLRequestContextAdapter : public net::URLRequestContextGetter { ...@@ -75,11 +89,22 @@ class URLRequestContextAdapter : public net::URLRequestContextGetter {
scoped_ptr<NetLogObserver> net_log_observer_; scoped_ptr<NetLogObserver> net_log_observer_;
scoped_ptr<net::NetLogLogger> net_log_logger_; scoped_ptr<net::NetLogLogger> net_log_logger_;
// A queue of tasks that need to be run after context has been initialized.
std::queue<RunAfterContextInitTask> tasks_waiting_for_context_;
bool is_context_initialized_;
virtual ~URLRequestContextAdapter(); virtual ~URLRequestContextAdapter();
// Initializes |context_| on the Network thread. // Initializes |context_| on the Network thread.
void InitializeURLRequestContext(scoped_ptr<URLRequestContextConfig> config); void InitializeURLRequestContext(scoped_ptr<URLRequestContextConfig> config);
// Helper function to start writing NetLog data to file. This should only be
// run after context is initialized.
void StartNetLogToFileHelper(const std::string& file_name);
// Helper function to stop writing NetLog data to file. This should only be
// run after context is initialized.
void StopNetLogHelper();
DISALLOW_COPY_AND_ASSIGN(URLRequestContextAdapter); DISALLOW_COPY_AND_ASSIGN(URLRequestContextAdapter);
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment