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

Side by Side Diff: chrome/renderer/extensions/request_sender.cc

Issue 12632004: Revert 186643 - Caused a 10% regression on SunSpider benchmark (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 7 years, 9 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/renderer/extensions/request_sender.h" 5 #include "chrome/renderer/extensions/request_sender.h"
6 6
7 #include "base/values.h" 7 #include "base/values.h"
8 #include "chrome/common/extensions/extension_messages.h" 8 #include "chrome/common/extensions/extension_messages.h"
9 #include "chrome/renderer/extensions/chrome_v8_context.h" 9 #include "chrome/renderer/extensions/chrome_v8_context.h"
10 #include "chrome/renderer/extensions/chrome_v8_context_set.h"
10 #include "chrome/renderer/extensions/dispatcher.h" 11 #include "chrome/renderer/extensions/dispatcher.h"
11 #include "content/public/renderer/render_view.h" 12 #include "content/public/renderer/render_view.h"
12 #include "content/public/renderer/v8_value_converter.h" 13 #include "content/public/renderer/v8_value_converter.h"
13 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" 14 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
14 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" 15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h" 16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h"
16 17
17 using content::V8ValueConverter; 18 using content::V8ValueConverter;
18 19
19 namespace extensions { 20 namespace extensions {
20 21
21 // Contains info relevant to a pending API request. 22 // Contains info relevant to a pending API request.
22 struct PendingRequest { 23 struct PendingRequest {
23 public : 24 public :
24 PendingRequest(const std::string& name, ChromeV8Context* context) 25 PendingRequest(v8::Persistent<v8::Context> context, const std::string& name,
25 : name(name), context(context) { 26 const std::string& extension_id)
27 : context(context), name(name), extension_id(extension_id) {
26 } 28 }
27 29
30 ~PendingRequest() {
31 context.Dispose(context->GetIsolate());
32 }
33
34 v8::Persistent<v8::Context> context;
28 std::string name; 35 std::string name;
29 ChromeV8Context* context; 36 std::string extension_id;
30 }; 37 };
31 38
32 RequestSender::RequestSender(Dispatcher* dispatcher) : dispatcher_(dispatcher) { 39 RequestSender::RequestSender(Dispatcher* dispatcher,
40 ChromeV8ContextSet* context_set)
41 : dispatcher_(dispatcher), context_set_(context_set) {
33 } 42 }
34 43
35 RequestSender::~RequestSender() { 44 RequestSender::~RequestSender() {
36 } 45 }
37 46
38 void RequestSender::InsertRequest(int request_id, 47 void RequestSender::InsertRequest(int request_id,
39 PendingRequest* pending_request) { 48 PendingRequest* pending_request) {
40 DCHECK_EQ(0u, pending_requests_.count(request_id)); 49 DCHECK_EQ(0u, pending_requests_.count(request_id));
41 pending_requests_[request_id].reset(pending_request); 50 pending_requests_[request_id].reset(pending_request);
42 } 51 }
43 52
44 linked_ptr<PendingRequest> RequestSender::RemoveRequest(int request_id) { 53 linked_ptr<PendingRequest> RequestSender::RemoveRequest(int request_id) {
45 PendingRequestMap::iterator i = pending_requests_.find(request_id); 54 PendingRequestMap::iterator i = pending_requests_.find(request_id);
46 if (i == pending_requests_.end()) 55 if (i == pending_requests_.end())
47 return linked_ptr<PendingRequest>(); 56 return linked_ptr<PendingRequest>();
48 linked_ptr<PendingRequest> result = i->second; 57 linked_ptr<PendingRequest> result = i->second;
49 pending_requests_.erase(i); 58 pending_requests_.erase(i);
50 return result; 59 return result;
51 } 60 }
52 61
53 void RequestSender::StartRequest(ChromeV8Context* context, 62 void RequestSender::StartRequest(const std::string& name,
54 const std::string& name,
55 int request_id, 63 int request_id,
56 bool has_callback, 64 bool has_callback,
57 bool for_io_thread, 65 bool for_io_thread,
58 base::ListValue* value_args) { 66 base::ListValue* value_args) {
67 ChromeV8Context* current_context = context_set_->GetCurrent();
68 if (!current_context)
69 return;
70
59 // Get the current RenderView so that we can send a routed IPC message from 71 // Get the current RenderView so that we can send a routed IPC message from
60 // the correct source. 72 // the correct source.
61 content::RenderView* renderview = context->GetRenderView(); 73 content::RenderView* renderview = current_context->GetRenderView();
62 if (!renderview) 74 if (!renderview)
63 return; 75 return;
64 76
65 const std::set<std::string>& function_names = dispatcher_->function_names(); 77 const std::set<std::string>& function_names = dispatcher_->function_names();
66 if (function_names.find(name) == function_names.end()) { 78 if (function_names.find(name) == function_names.end()) {
67 NOTREACHED() << "Unexpected function " << name << 79 NOTREACHED() << "Unexpected function " << name <<
68 ". Did you remember to register it with ExtensionFunctionRegistry?"; 80 ". Did you remember to register it with ExtensionFunctionRegistry?";
69 return; 81 return;
70 } 82 }
71 83
72 // TODO(koz): See if we can make this a CHECK. 84 // TODO(koz): See if we can make this a CHECK.
73 if (!dispatcher_->CheckContextAccessToExtensionAPI(name, context)) 85 if (!dispatcher_->CheckCurrentContextAccessToExtensionAPI(name))
74 return; 86 return;
75 87
76 GURL source_url; 88 GURL source_url;
77 WebKit::WebSecurityOrigin source_origin; 89 WebKit::WebSecurityOrigin source_origin;
78 WebKit::WebFrame* webframe = context->web_frame(); 90 WebKit::WebFrame* webframe = current_context->web_frame();
79 if (webframe) { 91 if (webframe) {
80 source_url = webframe->document().url(); 92 source_url = webframe->document().url();
81 source_origin = webframe->document().securityOrigin(); 93 source_origin = webframe->document().securityOrigin();
82 } 94 }
83 95
84 InsertRequest(request_id, new PendingRequest(name, context)); 96 v8::Local<v8::Context> ctx = v8::Context::GetCurrent();
97 v8::Persistent<v8::Context> v8_context =
98 v8::Persistent<v8::Context>::New(ctx->GetIsolate(), ctx);
99 DCHECK(!v8_context.IsEmpty());
100
101 std::string extension_id = current_context->GetExtensionID();
102 InsertRequest(request_id, new PendingRequest(
103 v8_context, name, extension_id));
85 104
86 ExtensionHostMsg_Request_Params params; 105 ExtensionHostMsg_Request_Params params;
87 params.name = name; 106 params.name = name;
88 params.arguments.Swap(value_args); 107 params.arguments.Swap(value_args);
89 params.extension_id = context->GetExtensionID(); 108 params.extension_id = extension_id;
90 params.source_url = source_url; 109 params.source_url = source_url;
91 params.source_origin = source_origin.toString(); 110 params.source_origin = source_origin.toString();
92 params.request_id = request_id; 111 params.request_id = request_id;
93 params.has_callback = has_callback; 112 params.has_callback = has_callback;
94 params.user_gesture = 113 params.user_gesture =
95 webframe ? webframe->isProcessingUserGesture() : false; 114 webframe ? webframe->isProcessingUserGesture() : false;
96 if (for_io_thread) { 115 if (for_io_thread) {
97 renderview->Send(new ExtensionHostMsg_RequestForIOThread( 116 renderview->Send(new ExtensionHostMsg_RequestForIOThread(
98 renderview->GetRoutingID(), params)); 117 renderview->GetRoutingID(), params));
99 } else { 118 } else {
100 renderview->Send(new ExtensionHostMsg_Request( 119 renderview->Send(new ExtensionHostMsg_Request(
101 renderview->GetRoutingID(), params)); 120 renderview->GetRoutingID(), params));
102 } 121 }
103 } 122 }
104 123
105 void RequestSender::HandleResponse(int request_id, 124 void RequestSender::HandleResponse(int request_id,
106 bool success, 125 bool success,
107 const base::ListValue& responseList, 126 const base::ListValue& responseList,
108 const std::string& error) { 127 const std::string& error) {
109 linked_ptr<PendingRequest> request = RemoveRequest(request_id); 128 linked_ptr<PendingRequest> request = RemoveRequest(request_id);
110 129
111 if (!request.get()) { 130 if (!request.get()) {
112 // This can happen if a context is destroyed while a request is in flight. 131 // This should not be able to happen since we only remove requests when
132 // they are handled.
133 LOG(ERROR) << "Could not find specified request id: " << request_id;
113 return; 134 return;
114 } 135 }
115 136
137 ChromeV8Context* v8_context = context_set_->GetByV8Context(request->context);
138 if (!v8_context)
139 return; // The frame went away.
140
116 v8::HandleScope handle_scope; 141 v8::HandleScope handle_scope;
117 142
118 scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create()); 143 scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create());
119 v8::Handle<v8::Value> argv[] = { 144 v8::Handle<v8::Value> argv[] = {
120 v8::Integer::New(request_id), 145 v8::Integer::New(request_id),
121 v8::String::New(request->name.c_str()), 146 v8::String::New(request->name.c_str()),
122 v8::Boolean::New(success), 147 v8::Boolean::New(success),
123 converter->ToV8Value(&responseList, request->context->v8_context()), 148 converter->ToV8Value(&responseList, v8_context->v8_context()),
124 v8::String::New(error.c_str()) 149 v8::String::New(error.c_str())
125 }; 150 };
126 151
127 v8::Handle<v8::Value> retval; 152 v8::Handle<v8::Value> retval;
128 CHECK(request->context->CallChromeHiddenMethod("handleResponse", 153 CHECK(v8_context->CallChromeHiddenMethod("handleResponse",
129 arraysize(argv), 154 arraysize(argv),
130 argv, 155 argv,
131 &retval)); 156 &retval));
132 // In debug, the js will validate the callback parameters and return a 157 // In debug, the js will validate the callback parameters and return a
133 // string if a validation error has occured. 158 // string if a validation error has occured.
134 if (DCHECK_IS_ON()) { 159 if (DCHECK_IS_ON()) {
135 if (!retval.IsEmpty() && !retval->IsUndefined()) { 160 if (!retval.IsEmpty() && !retval->IsUndefined()) {
136 std::string error = *v8::String::AsciiValue(retval); 161 std::string error = *v8::String::AsciiValue(retval);
137 DCHECK(false) << error; 162 DCHECK(false) << error;
138 } 163 }
139 } 164 }
140 } 165 }
141 166
142 void RequestSender::InvalidateContext(ChromeV8Context* context) {
143 for (PendingRequestMap::iterator it = pending_requests_.begin();
144 it != pending_requests_.end();) {
145 if (it->second->context == context)
146 pending_requests_.erase(it++);
147 else
148 ++it;
149 }
150 }
151
152 } // namespace extensions 167 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/renderer/extensions/request_sender.h ('k') | chrome/renderer/extensions/runtime_custom_bindings.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698