summaryrefslogtreecommitdiffstats
path: root/chrome/renderer/extensions
diff options
context:
space:
mode:
authormpcomplete@chromium.org <mpcomplete@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-21 18:50:54 +0000
committermpcomplete@chromium.org <mpcomplete@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-21 18:50:54 +0000
commitcf3ac1f27fcd2986b62262f4f458dc9c2a519732 (patch)
tree8f62092348d503a30c60ec119cb5cc2a3281f151 /chrome/renderer/extensions
parent9e3cadc39f990c2955e1c6bfeb8686fa6f25ad85 (diff)
downloadchromium_src-cf3ac1f27fcd2986b62262f4f458dc9c2a519732.zip
chromium_src-cf3ac1f27fcd2986b62262f4f458dc9c2a519732.tar.gz
chromium_src-cf3ac1f27fcd2986b62262f4f458dc9c2a519732.tar.bz2
Don't dispatch the extensions bindings unload event during GC.
BUG=17289 TEST=no Review URL: http://codereview.chromium.org/159095 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@21197 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/renderer/extensions')
-rw-r--r--chrome/renderer/extensions/event_bindings.cc38
1 files changed, 26 insertions, 12 deletions
diff --git a/chrome/renderer/extensions/event_bindings.cc b/chrome/renderer/extensions/event_bindings.cc
index 9d7104c..863ebbf 100644
--- a/chrome/renderer/extensions/event_bindings.cc
+++ b/chrome/renderer/extensions/event_bindings.cc
@@ -122,12 +122,24 @@ RenderThreadBase* EventBindings::GetRenderThread() {
return render_thread ? render_thread : RenderThread::current();
}
+static void DeferredUnload(v8::Persistent<v8::Context> context) {
+ v8::HandleScope handle_scope;
+ CallFunctionInContext(context, "dispatchOnUnload", 0, NULL);
+ context.Dispose();
+ context.Clear();
+}
+
static void HandleContextDestroyed(ContextList::iterator context_iter,
- bool callUnload) {
+ bool in_gc) {
// Notify the bindings that they're going away.
- if (callUnload) {
- CallFunctionInContext((*context_iter)->context, "dispatchOnUnload", 0,
- NULL);
+ if (in_gc) {
+ // We shouldn't call back into javascript during a garbage collect. Do it
+ // later. We'll hang onto the context until this DeferredUnload is called.
+ MessageLoop::current()->PostTask(FROM_HERE, NewRunnableFunction(
+ DeferredUnload, (*context_iter)->context));
+ } else {
+ CallFunctionInContext((*context_iter)->context, "dispatchOnUnload",
+ 0, NULL);
}
// Remove all pending requests for this context.
@@ -147,19 +159,21 @@ static void HandleContextDestroyed(ContextList::iterator context_iter,
it != GetContexts().end(); ) {
ContextList::iterator current = it++;
if ((*current)->parent_context == (*context_iter)->context)
- HandleContextDestroyed(current, callUnload);
+ HandleContextDestroyed(current, in_gc);
}
- // Remove it from our registered contexts.
- (*context_iter)->context.ClearWeak();
- (*context_iter)->context.Dispose();
- (*context_iter)->context.Clear();
-
if (!(*context_iter)->parent_context.IsEmpty()) {
(*context_iter)->parent_context.Dispose();
(*context_iter)->parent_context.Clear();
}
+ // Remove it from our registered contexts.
+ (*context_iter)->context.ClearWeak();
+ if (!in_gc) {
+ (*context_iter)->context.Dispose();
+ (*context_iter)->context.Clear();
+ }
+
GetContexts().erase(context_iter);
}
@@ -168,7 +182,7 @@ static void ContextWeakReferenceCallback(v8::Persistent<v8::Value> context,
for (ContextList::iterator it = GetContexts().begin();
it != GetContexts().end(); ++it) {
if ((*it)->context == context) {
- HandleContextDestroyed(it, false);
+ HandleContextDestroyed(it, true);
return;
}
}
@@ -244,7 +258,7 @@ void EventBindings::HandleContextDestroyed(WebFrame* frame) {
ContextList::iterator context_iter = bindings_utils::FindContext(context);
if (context_iter != GetContexts().end())
- ::HandleContextDestroyed(context_iter, true);
+ ::HandleContextDestroyed(context_iter, false);
}
// static