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

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

Issue 159095: Don't dispatch the extensions bindings unload event during GC. (Closed)
Patch Set: messed up the if Created 11 years, 5 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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/event_bindings.h" 5 #include "chrome/renderer/extensions/event_bindings.h"
6 6
7 #include "base/basictypes.h" 7 #include "base/basictypes.h"
8 #include "base/singleton.h" 8 #include "base/singleton.h"
9 #include "chrome/common/render_messages.h" 9 #include "chrome/common/render_messages.h"
10 #include "chrome/common/url_constants.h" 10 #include "chrome/common/url_constants.h"
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 void EventBindings::SetRenderThread(RenderThreadBase* thread) { 115 void EventBindings::SetRenderThread(RenderThreadBase* thread) {
116 render_thread = thread; 116 render_thread = thread;
117 in_unit_tests = true; 117 in_unit_tests = true;
118 } 118 }
119 119
120 // static 120 // static
121 RenderThreadBase* EventBindings::GetRenderThread() { 121 RenderThreadBase* EventBindings::GetRenderThread() {
122 return render_thread ? render_thread : RenderThread::current(); 122 return render_thread ? render_thread : RenderThread::current();
123 } 123 }
124 124
125 static void DeferredUnload(v8::Persistent<v8::Context> context) {
126 v8::HandleScope handle_scope;
127 CallFunctionInContext(context, "dispatchOnUnload", 0, NULL);
128 context.Dispose();
129 context.Clear();
130 }
131
125 static void HandleContextDestroyed(ContextList::iterator context_iter, 132 static void HandleContextDestroyed(ContextList::iterator context_iter,
126 bool callUnload) { 133 bool in_gc) {
127 // Notify the bindings that they're going away. 134 // Notify the bindings that they're going away.
128 if (callUnload) { 135 if (in_gc) {
129 CallFunctionInContext((*context_iter)->context, "dispatchOnUnload", 0, 136 // We shouldn't call back into javascript during a garbage collect. Do it
130 NULL); 137 // later. We'll hang onto the context until this DeferredUnload is called.
138 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableFunction(
139 DeferredUnload, (*context_iter)->context));
140 } else {
141 CallFunctionInContext((*context_iter)->context, "dispatchOnUnload",
142 0, NULL);
131 } 143 }
132 144
133 // Remove all pending requests for this context. 145 // Remove all pending requests for this context.
134 PendingRequestMap& pending_requests = GetPendingRequestMap(); 146 PendingRequestMap& pending_requests = GetPendingRequestMap();
135 for (PendingRequestMap::iterator it = pending_requests.begin(); 147 for (PendingRequestMap::iterator it = pending_requests.begin();
136 it != pending_requests.end(); ) { 148 it != pending_requests.end(); ) {
137 PendingRequestMap::iterator current = it++; 149 PendingRequestMap::iterator current = it++;
138 if (current->second->context == (*context_iter)->context) { 150 if (current->second->context == (*context_iter)->context) {
139 current->second->context.Dispose(); 151 current->second->context.Dispose();
140 current->second->context.Clear(); 152 current->second->context.Clear();
141 pending_requests.erase(current); 153 pending_requests.erase(current);
142 } 154 }
143 } 155 }
144 156
145 // Unload any content script contexts for this frame. 157 // Unload any content script contexts for this frame.
146 for (ContextList::iterator it = GetContexts().begin(); 158 for (ContextList::iterator it = GetContexts().begin();
147 it != GetContexts().end(); ) { 159 it != GetContexts().end(); ) {
148 ContextList::iterator current = it++; 160 ContextList::iterator current = it++;
149 if ((*current)->parent_context == (*context_iter)->context) 161 if ((*current)->parent_context == (*context_iter)->context)
150 HandleContextDestroyed(current, callUnload); 162 HandleContextDestroyed(current, in_gc);
151 } 163 }
152 164
153 // Remove it from our registered contexts.
154 (*context_iter)->context.ClearWeak();
155 (*context_iter)->context.Dispose();
156 (*context_iter)->context.Clear();
157
158 if (!(*context_iter)->parent_context.IsEmpty()) { 165 if (!(*context_iter)->parent_context.IsEmpty()) {
159 (*context_iter)->parent_context.Dispose(); 166 (*context_iter)->parent_context.Dispose();
160 (*context_iter)->parent_context.Clear(); 167 (*context_iter)->parent_context.Clear();
161 } 168 }
162 169
170 // Remove it from our registered contexts.
171 (*context_iter)->context.ClearWeak();
172 if (!in_gc) {
173 (*context_iter)->context.Dispose();
174 (*context_iter)->context.Clear();
175 }
176
163 GetContexts().erase(context_iter); 177 GetContexts().erase(context_iter);
164 } 178 }
165 179
166 static void ContextWeakReferenceCallback(v8::Persistent<v8::Value> context, 180 static void ContextWeakReferenceCallback(v8::Persistent<v8::Value> context,
167 void*) { 181 void*) {
168 for (ContextList::iterator it = GetContexts().begin(); 182 for (ContextList::iterator it = GetContexts().begin();
169 it != GetContexts().end(); ++it) { 183 it != GetContexts().end(); ++it) {
170 if ((*it)->context == context) { 184 if ((*it)->context == context) {
171 HandleContextDestroyed(it, false); 185 HandleContextDestroyed(it, true);
172 return; 186 return;
173 } 187 }
174 } 188 }
175 189
176 NOTREACHED(); 190 NOTREACHED();
177 } 191 }
178 192
179 void EventBindings::HandleContextCreated(WebFrame* frame, bool content_script) { 193 void EventBindings::HandleContextCreated(WebFrame* frame, bool content_script) {
180 if (!bindings_registered) 194 if (!bindings_registered)
181 return; 195 return;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 void EventBindings::HandleContextDestroyed(WebFrame* frame) { 251 void EventBindings::HandleContextDestroyed(WebFrame* frame) {
238 if (!bindings_registered) 252 if (!bindings_registered)
239 return; 253 return;
240 254
241 v8::HandleScope handle_scope; 255 v8::HandleScope handle_scope;
242 v8::Local<v8::Context> context = frame->GetScriptContext(); 256 v8::Local<v8::Context> context = frame->GetScriptContext();
243 DCHECK(!context.IsEmpty()); 257 DCHECK(!context.IsEmpty());
244 258
245 ContextList::iterator context_iter = bindings_utils::FindContext(context); 259 ContextList::iterator context_iter = bindings_utils::FindContext(context);
246 if (context_iter != GetContexts().end()) 260 if (context_iter != GetContexts().end())
247 ::HandleContextDestroyed(context_iter, true); 261 ::HandleContextDestroyed(context_iter, false);
248 } 262 }
249 263
250 // static 264 // static
251 void EventBindings::CallFunction(const std::string& function_name, 265 void EventBindings::CallFunction(const std::string& function_name,
252 int argc, v8::Handle<v8::Value>* argv, 266 int argc, v8::Handle<v8::Value>* argv,
253 RenderView* render_view) { 267 RenderView* render_view) {
254 for (ContextList::iterator it = GetContexts().begin(); 268 for (ContextList::iterator it = GetContexts().begin();
255 it != GetContexts().end(); ++it) { 269 it != GetContexts().end(); ++it) {
256 if (render_view && render_view != (*it)->render_view) 270 if (render_view && render_view != (*it)->render_view)
257 continue; 271 continue;
258 CallFunctionInContext((*it)->context, function_name, argc, argv); 272 CallFunctionInContext((*it)->context, function_name, argc, argv);
259 } 273 }
260 } 274 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698