From bff2be05175f76909a9280e55302355e7d1fa9c0 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Fri, 7 Dec 2012 12:58:14 +1300 Subject: [PATCH] Bug 785348. Part 1: Track when we've called into plugin code. While we're in plugin code, never run the refresh driver. r=mats --HG-- extra : rebase_source : 2ddabda92acc1364d3c24cf20f7d45896ac09849 --- dom/plugins/base/nsNPAPIPlugin.cpp | 8 ++++++++ dom/plugins/base/nsNPAPIPluginInstance.cpp | 2 ++ dom/plugins/base/nsNPAPIPluginInstance.h | 10 ++++++++++ dom/plugins/base/nsPluginSafety.h | 23 +++++++++++----------- layout/base/nsRefreshDriver.cpp | 9 ++++++--- 5 files changed, 38 insertions(+), 14 deletions(-) diff --git a/dom/plugins/base/nsNPAPIPlugin.cpp b/dom/plugins/base/nsNPAPIPlugin.cpp index 694c1535111e..ed5f26b7813a 100644 --- a/dom/plugins/base/nsNPAPIPlugin.cpp +++ b/dom/plugins/base/nsNPAPIPlugin.cpp @@ -186,12 +186,20 @@ enum eNPPStreamTypeInternal { static NS_DEFINE_IID(kMemoryCID, NS_MEMORY_CID); +PRIntervalTime NS_NotifyBeginPluginCall() +{ + nsNPAPIPluginInstance::BeginPluginCall(); + return PR_IntervalNow(); +} + // This function sends a notification using the observer service to any object // registered to listen to the "experimental-notify-plugin-call" subject. // Each "experimental-notify-plugin-call" notification carries with it the run // time value in milliseconds that the call took to execute. void NS_NotifyPluginCall(PRIntervalTime startTime) { + nsNPAPIPluginInstance::EndPluginCall(); + PRIntervalTime endTime = PR_IntervalNow() - startTime; nsCOMPtr notifyUIService = mozilla::services::GetObserverService(); diff --git a/dom/plugins/base/nsNPAPIPluginInstance.cpp b/dom/plugins/base/nsNPAPIPluginInstance.cpp index f7226365aebc..467261eaf277 100644 --- a/dom/plugins/base/nsNPAPIPluginInstance.cpp +++ b/dom/plugins/base/nsNPAPIPluginInstance.cpp @@ -200,6 +200,8 @@ nsNPAPIPluginInstance::~nsNPAPIPluginInstance() } } +uint32_t nsNPAPIPluginInstance::gInPluginCalls = 0; + void nsNPAPIPluginInstance::Destroy() { diff --git a/dom/plugins/base/nsNPAPIPluginInstance.h b/dom/plugins/base/nsNPAPIPluginInstance.h index 98bcf4227d01..935689503f16 100644 --- a/dom/plugins/base/nsNPAPIPluginInstance.h +++ b/dom/plugins/base/nsNPAPIPluginInstance.h @@ -270,6 +270,14 @@ public: // Returns the contents scale factor of the screen the plugin is drawn on. double GetContentsScaleFactor(); + static bool InPluginCall() { return gInPluginCalls > 0; } + static void BeginPluginCall() { ++gInPluginCalls; } + static void EndPluginCall() + { + NS_ASSERTION(InPluginCall(), "Must be in plugin call"); + --gInPluginCalls; + } + protected: nsresult GetTagType(nsPluginTagType *result); @@ -364,6 +372,8 @@ private: // is this instance Java and affected by bug 750480? bool mHaveJavaC2PJSObjectQuirk; + + static uint32_t gInPluginCalls; }; #endif // nsNPAPIPluginInstance_h_ diff --git a/dom/plugins/base/nsPluginSafety.h b/dom/plugins/base/nsPluginSafety.h index 1483f459639a..50b4162908ac 100644 --- a/dom/plugins/base/nsPluginSafety.h +++ b/dom/plugins/base/nsPluginSafety.h @@ -14,6 +14,7 @@ #define CALL_SAFETY_ON #endif +PRIntervalTime NS_NotifyBeginPluginCall(); void NS_NotifyPluginCall(PRIntervalTime); #ifdef CALL_SAFETY_ON @@ -31,7 +32,7 @@ PR_END_MACRO #define NS_TRY_SAFE_CALL_RETURN(ret, fun, pluginInst) \ PR_BEGIN_MACRO \ - PRIntervalTime startTime = PR_IntervalNow(); \ + PRIntervalTime startTime = NS_NotifyBeginPluginCall(); \ if(gSkipPluginSafeCalls) \ ret = fun; \ else \ @@ -40,7 +41,7 @@ PR_BEGIN_MACRO \ { \ ret = fun; \ } \ - MOZ_SEH_EXCEPT(true) \ + MOZ_SEH_EXCEPT(true) \ { \ nsresult res; \ nsCOMPtr host(do_GetService(MOZ_PLUGIN_HOST_CONTRACTID, &res));\ @@ -54,7 +55,7 @@ PR_END_MACRO #define NS_TRY_SAFE_CALL_VOID(fun, pluginInst) \ PR_BEGIN_MACRO \ - PRIntervalTime startTime = PR_IntervalNow(); \ + PRIntervalTime startTime = NS_NotifyBeginPluginCall(); \ if(gSkipPluginSafeCalls) \ fun; \ else \ @@ -63,7 +64,7 @@ PR_BEGIN_MACRO \ { \ fun; \ } \ - MOZ_SEH_EXCEPT(true) \ + MOZ_SEH_EXCEPT(true) \ { \ nsresult res; \ nsCOMPtr host(do_GetService(MOZ_PLUGIN_HOST_CONTRACTID, &res));\ @@ -78,16 +79,16 @@ PR_END_MACRO #define NS_TRY_SAFE_CALL_RETURN(ret, fun, pluginInst) \ PR_BEGIN_MACRO \ - PRIntervalTime startTime = PR_IntervalNow(); \ + PRIntervalTime startTime = NS_NotifyBeginPluginCall(); \ ret = fun; \ - NS_NotifyPluginCall(startTime); \ + NS_NotifyPluginCall(startTime); \ PR_END_MACRO -#define NS_TRY_SAFE_CALL_VOID(fun, pluginInst) \ -PR_BEGIN_MACRO \ - PRIntervalTime startTime = PR_IntervalNow(); \ - fun; \ - NS_NotifyPluginCall(startTime); \ +#define NS_TRY_SAFE_CALL_VOID(fun, pluginInst) \ +PR_BEGIN_MACRO \ + PRIntervalTime startTime = NS_NotifyBeginPluginCall(); \ + fun; \ + NS_NotifyPluginCall(startTime); \ PR_END_MACRO #endif // CALL_SAFETY_ON diff --git a/layout/base/nsRefreshDriver.cpp b/layout/base/nsRefreshDriver.cpp index 0935d4b1f741..cf8ee866a7f7 100644 --- a/layout/base/nsRefreshDriver.cpp +++ b/layout/base/nsRefreshDriver.cpp @@ -25,9 +25,7 @@ #include "mozilla/Preferences.h" #include "nsIViewManager.h" #include "sampler.h" - -using mozilla::TimeStamp; -using mozilla::TimeDuration; +#include "nsNPAPIPluginInstance.h" using namespace mozilla; @@ -310,6 +308,11 @@ nsRefreshDriver::Notify(nsITimer *aTimer) NS_PRECONDITION(mPresContext, "Why are we notified after disconnection?"); NS_PRECONDITION(!nsContentUtils::GetCurrentJSContext(), "Shouldn't have a JSContext on the stack"); + if (nsNPAPIPluginInstance::InPluginCall()) { + NS_ERROR("Refresh driver should not run during plugin call!"); + // Try to survive this by just ignoring the refresh tick. + return NS_OK; + } if (mTestControllingRefreshes && aTimer) { // Ignore real refreshes from our timer (but honor the others).