Index: chrome/browser/devtools/devtools_ui_bindings.cc |
diff --git a/chrome/browser/devtools/devtools_ui_bindings.cc b/chrome/browser/devtools/devtools_ui_bindings.cc |
index 8ecab6e921c5ba4fae985a046276644eb4e783a1..56f102d98ba83d96d07c7a650ea57459f83543e5 100644 |
--- a/chrome/browser/devtools/devtools_ui_bindings.cc |
+++ b/chrome/browser/devtools/devtools_ui_bindings.cc |
@@ -79,10 +79,14 @@ static const int kDevToolsPanelShownBoundary = 20; |
// the constant at shell_devtools_frontend.cc. |
const size_t kMaxMessageChunkSize = IPC::Channel::kMaximumMessageSize / 4; |
-typedef std::vector<DevToolsUIBindings*> DevToolsUIBindingsList; |
+using DevToolsUIBindingsList = std::vector<DevToolsUIBindings*>; |
base::LazyInstance<DevToolsUIBindingsList>::Leaky g_instances = |
LAZY_INSTANCE_INITIALIZER; |
+using StreamOwners = std::map<int, DevToolsUIBindings*>; |
+base::LazyInstance<StreamOwners>::Leaky g_stream_owners = |
+ LAZY_INSTANCE_INITIALIZER; |
+ |
std::string SkColorToRGBAString(SkColor color) { |
// We avoid StringPrintf because it will use locale specific formatters for |
// the double (e.g. ',' instead of '.' in German). |
@@ -242,7 +246,7 @@ InfoBarService* DefaultBindingsDelegate::GetInfoBarService() { |
class ResponseWriter : public net::URLFetcherResponseWriter { |
public: |
- ResponseWriter(DevToolsUIBindings* bindings, int stream_id); |
+ explicit ResponseWriter(int stream_id); |
~ResponseWriter() override; |
// URLFetcherResponseWriter overrides: |
@@ -253,16 +257,13 @@ class ResponseWriter : public net::URLFetcherResponseWriter { |
int Finish(const net::CompletionCallback& callback) override; |
private: |
- DevToolsUIBindings* bindings_; |
int stream_id_; |
DISALLOW_COPY_AND_ASSIGN(ResponseWriter); |
}; |
-ResponseWriter::ResponseWriter(DevToolsUIBindings* bindings, |
- int stream_id) |
- : bindings_(bindings), |
- stream_id_(stream_id) { |
+ResponseWriter::ResponseWriter(int stream_id) |
+ : stream_id_(stream_id) { |
} |
ResponseWriter::~ResponseWriter() { |
@@ -272,20 +273,39 @@ int ResponseWriter::Initialize(const net::CompletionCallback& callback) { |
return net::OK; |
} |
+static void WriteResponseOnUI(int stream_id, const std::string& chunk) { |
+ auto it = g_stream_owners.Get().find(stream_id); |
+ if (it != g_stream_owners.Get().end()) { |
+ base::FundamentalValue id(stream_id); |
+ base::StringValue value(chunk); |
+ it->second->CallClientFunction( |
+ "DevToolsAPI.streamWrite", &id, &value, nullptr); |
+ } |
+} |
+ |
int ResponseWriter::Write(net::IOBuffer* buffer, |
int num_bytes, |
const net::CompletionCallback& callback) { |
- base::FundamentalValue id(stream_id_); |
- base::StringValue chunk(std::string(buffer->data(), num_bytes)); |
- bindings_->CallClientFunction( |
- "DevToolsAPI.streamWrite", &id, &chunk, nullptr); |
+ content::BrowserThread::PostTask( |
+ content::BrowserThread::UI, FROM_HERE, |
+ base::Bind(&WriteResponseOnUI, stream_id_, |
+ std::string(buffer->data(), num_bytes))); |
return num_bytes; |
} |
+static void FinishResponseOnUI(int stream_id) { |
+ auto it = g_stream_owners.Get().find(stream_id); |
+ if (it != g_stream_owners.Get().end()) { |
+ base::FundamentalValue id(stream_id); |
+ it->second->CallClientFunction( |
+ "DevToolsAPI.streamFinish", &id, nullptr, nullptr); |
+ } |
+} |
+ |
int ResponseWriter::Finish(const net::CompletionCallback& callback) { |
- base::FundamentalValue id(stream_id_); |
- bindings_->CallClientFunction( |
- "DevToolsAPI.streamFinish", &id, nullptr, nullptr); |
+ content::BrowserThread::PostTask( |
+ content::BrowserThread::UI, FROM_HERE, |
+ base::Bind(&FinishResponseOnUI, stream_id_)); |
return net::OK; |
} |
@@ -442,6 +462,14 @@ DevToolsUIBindings::~DevToolsUIBindings() { |
for (const auto& pair : pending_requests_) |
delete pair.first; |
+ for (auto it = g_stream_owners.Get().begin(); |
+ it != g_stream_owners.Get().end(); ) { |
+ if (it->second == this) |
+ g_stream_owners.Get().erase(it); |
+ else |
+ ++it; |
+ } |
+ |
if (agent_host_.get()) |
agent_host_->DetachClient(); |
@@ -581,13 +609,15 @@ void DevToolsUIBindings::LoadNetworkResource(int request_id, |
return; |
} |
+ g_stream_owners.Get()[stream_id] = this; |
dgozman
2015/02/28 16:06:13
This will make streams from different DevTools cla
|
+ |
net::URLFetcher* fetcher = |
net::URLFetcher::Create(gurl, net::URLFetcher::GET, this); |
- pending_requests_[fetcher] = request_id; |
+ pending_requests_[fetcher] = std::make_pair(request_id, stream_id); |
fetcher->SetRequestContext(profile_->GetRequestContext()); |
fetcher->SetExtraRequestHeaders(headers); |
fetcher->SaveResponseWithWriter(scoped_ptr<net::URLFetcherResponseWriter>( |
- new ResponseWriter(this, stream_id))); |
+ new ResponseWriter(stream_id))); |
fetcher->Start(); |
} |
@@ -803,7 +833,10 @@ void DevToolsUIBindings::OnURLFetchComplete(const net::URLFetcher* source) { |
while (rh && rh->EnumerateHeaderLines(&iterator, &name, &value)) |
headers->SetString(name, value); |
- SendMessageAck(it->second, &response); |
+ int request_id = it->second.first; |
+ int stream_id = it->second.second; |
+ SendMessageAck(request_id, &response); |
+ g_stream_owners.Get().erase(stream_id); |
pending_requests_.erase(it); |
delete source; |
} |