diff options
author | mpcomplete@chromium.org <mpcomplete@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-21 18:50:54 +0000 |
---|---|---|
committer | mpcomplete@chromium.org <mpcomplete@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-21 18:50:54 +0000 |
commit | cf3ac1f27fcd2986b62262f4f458dc9c2a519732 (patch) | |
tree | 8f62092348d503a30c60ec119cb5cc2a3281f151 /chrome/renderer/extensions | |
parent | 9e3cadc39f990c2955e1c6bfeb8686fa6f25ad85 (diff) | |
download | chromium_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.cc | 38 |
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 |