☠☠ backed out by 0a91da5f5eab ☠ ☠ | |
author | Robert O'Callahan <robert@ocallahan.org> |
Thu, 28 Feb 2013 00:50:27 +1300 | |
changeset 123141 | f73b7b8d1a2dc58c8892b551cd427f135efb6337 |
parent 123140 | abffab917ab76e607b95fbf38efb41844accabec |
child 123142 | 622b744e5df9387fa352791b415b85fa9b1d0ef5 |
push id | 24372 |
push user | emorley@mozilla.com |
push date | Wed, 27 Feb 2013 13:22:59 +0000 |
treeherder | mozilla-central@0a91da5f5eab [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | bsmedberg |
bugs | 829557 |
milestone | 22.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/dom/plugins/base/Makefile.in +++ b/dom/plugins/base/Makefile.in @@ -36,16 +36,17 @@ EXPORTS = \ npfunctions.h \ nptypes.h \ npruntime.h \ nsPluginLogging.h \ nsPluginNativeWindow.h \ nsPluginsCID.h \ nsNPAPIPluginInstance.h \ nsPluginsDir.h \ + nsPluginSafety.h \ nsPluginTags.h \ nsPluginDirServiceProvider.h \ nsPluginHost.h \ nsPluginInstanceOwner.h \ nsPluginPlayPreviewInfo.h \ $(NULL) EXPORTS_mozilla = \
--- a/dom/plugins/base/nsNPAPIPlugin.cpp +++ b/dom/plugins/base/nsNPAPIPlugin.cpp @@ -181,29 +181,29 @@ static PRCList sPendingAsyncCalls = PR_I // POST/GET stream type enum eNPPStreamTypeInternal { eNPPStreamTypeInternal_Get, eNPPStreamTypeInternal_Post }; static NS_DEFINE_IID(kMemoryCID, NS_MEMORY_CID); -PRIntervalTime NS_NotifyBeginPluginCall() +PRIntervalTime NS_NotifyBeginPluginCall(NSPluginCallReentry aReentryState) { - nsNPAPIPluginInstance::BeginPluginCall(); + nsNPAPIPluginInstance::BeginPluginCall(aReentryState); 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) +void NS_NotifyPluginCall(PRIntervalTime startTime, NSPluginCallReentry aReentryState) { - nsNPAPIPluginInstance::EndPluginCall(); + nsNPAPIPluginInstance::EndPluginCall(aReentryState); PRIntervalTime endTime = PR_IntervalNow() - startTime; nsCOMPtr<nsIObserverService> notifyUIService = mozilla::services::GetObserverService(); if (!notifyUIService) return; float runTimeInSeconds = float(endTime) / PR_TicksPerSecond(); @@ -784,17 +784,18 @@ nsPluginThreadRunnable::~nsPluginThreadR } NS_IMETHODIMP nsPluginThreadRunnable::Run() { if (mFunc) { PluginDestructionGuard guard(mInstance); - NS_TRY_SAFE_CALL_VOID(mFunc(mUserData), nullptr); + NS_TRY_SAFE_CALL_VOID(mFunc(mUserData), nullptr, + NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO); } return NS_OK; } void OnPluginDestroy(NPP instance) {
--- a/dom/plugins/base/nsNPAPIPluginInstance.cpp +++ b/dom/plugins/base/nsNPAPIPluginInstance.cpp @@ -208,17 +208,17 @@ nsNPAPIPluginInstance::~nsNPAPIPluginIns #endif if (mMIMEType) { PR_Free((void *)mMIMEType); mMIMEType = nullptr; } } -uint32_t nsNPAPIPluginInstance::gInPluginCalls = 0; +uint32_t nsNPAPIPluginInstance::gInUnsafePluginCalls = 0; void nsNPAPIPluginInstance::Destroy() { Stop(); mPlugin = nullptr; #if MOZ_WIDGET_ANDROID @@ -312,17 +312,18 @@ nsresult nsNPAPIPluginInstance::Stop() return NS_ERROR_FAILURE; NPPluginFuncs* pluginFunctions = mPlugin->PluginFuncs(); NPError error = NPERR_GENERIC_ERROR; if (pluginFunctions->destroy) { NPSavedData *sdata = 0; - NS_TRY_SAFE_CALL_RETURN(error, (*pluginFunctions->destroy)(&mNPP, &sdata), this); + NS_TRY_SAFE_CALL_RETURN(error, (*pluginFunctions->destroy)(&mNPP, &sdata), this, + NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO); NPP_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPP Destroy called: this=%p, npp=%p, return=%d\n", this, &mNPP, error)); } mRunning = DESTROYED; #if MOZ_WIDGET_ANDROID for (uint32_t i = 0; i < mPostedEvents.Length(); i++) { @@ -577,17 +578,18 @@ nsresult nsNPAPIPluginInstance::SetWindo PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("nsNPAPIPluginInstance::SetWindow (about to call it) this=%p\n",this)); bool oldVal = mInPluginInitCall; mInPluginInitCall = true; NPPAutoPusher nppPusher(&mNPP); DebugOnly<NPError> error; - NS_TRY_SAFE_CALL_RETURN(error, (*pluginFunctions->setwindow)(&mNPP, (NPWindow*)window), this); + NS_TRY_SAFE_CALL_RETURN(error, (*pluginFunctions->setwindow)(&mNPP, (NPWindow*)window), this, + NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO); mInPluginInitCall = oldVal; NPP_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPP SetWindow called: this=%p, [x=%d,y=%d,w=%d,h=%d], clip[t=%d,b=%d,l=%d,r=%d], return=%d\n", this, window->x, window->y, window->width, window->height, window->clipRect.top, window->clipRect.bottom, window->clipRect.left, window->clipRect.right, (NPError)error)); } @@ -645,17 +647,18 @@ nsresult nsNPAPIPluginInstance::Print(NP void** destination = (void **)&(thePrint->print.embedPrint.window.type); *destination = source; } else { NS_ERROR("Incompatible OS for assignment"); } } if (pluginFunctions->print) - NS_TRY_SAFE_CALL_VOID((*pluginFunctions->print)(&mNPP, thePrint), this); + NS_TRY_SAFE_CALL_VOID((*pluginFunctions->print)(&mNPP, thePrint), this, + NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO); NPP_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPP PrintProc called: this=%p, pDC=%p, [x=%d,y=%d,w=%d,h=%d], clip[t=%d,b=%d,l=%d,r=%d]\n", this, platformPrint->print.embedPrint.platformPrint, platformPrint->print.embedPrint.window.x, platformPrint->print.embedPrint.window.y, platformPrint->print.embedPrint.window.width, @@ -683,17 +686,18 @@ nsresult nsNPAPIPluginInstance::HandleEv NPPluginFuncs* pluginFunctions = mPlugin->PluginFuncs(); int16_t tmpResult = kNPEventNotHandled; if (pluginFunctions->event) { mCurrentPluginEvent = event; #if defined(XP_WIN) || defined(XP_OS2) - NS_TRY_SAFE_CALL_RETURN(tmpResult, (*pluginFunctions->event)(&mNPP, event), this); + NS_TRY_SAFE_CALL_RETURN(tmpResult, (*pluginFunctions->event)(&mNPP, event), this, + NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO); #else MAIN_THREAD_JNI_REF_GUARD; tmpResult = (*pluginFunctions->event)(&mNPP, event); #endif NPP_PLUGIN_LOG(PLUGIN_LOG_NOISY, ("NPP HandleEvent called: this=%p, npp=%p, event=%p, return=%d\n", this, &mNPP, event, tmpResult)); @@ -713,17 +717,18 @@ nsresult nsNPAPIPluginInstance::GetValue NPPluginFuncs* pluginFunctions = mPlugin->PluginFuncs(); nsresult rv = NS_ERROR_FAILURE; if (pluginFunctions->getvalue && RUNNING == mRunning) { PluginDestructionGuard guard(this); NPError pluginError = NPERR_GENERIC_ERROR; - NS_TRY_SAFE_CALL_RETURN(pluginError, (*pluginFunctions->getvalue)(&mNPP, variable, value), this); + NS_TRY_SAFE_CALL_RETURN(pluginError, (*pluginFunctions->getvalue)(&mNPP, variable, value), this, + NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO); NPP_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPP GetValue called: this=%p, npp=%p, var=%d, value=%d, return=%d\n", this, &mNPP, variable, value, pluginError)); if (pluginError == NPERR_NO_ERROR) { rv = NS_OK; } } @@ -1399,17 +1404,18 @@ nsNPAPIPluginInstance::PrivateModeStateC if (!pluginFunctions->setvalue) return NS_ERROR_FAILURE; PluginDestructionGuard guard(this); NPError error; NPBool value = static_cast<NPBool>(enabled); - NS_TRY_SAFE_CALL_RETURN(error, (*pluginFunctions->setvalue)(&mNPP, NPNVprivateModeBool, &value), this); + NS_TRY_SAFE_CALL_RETURN(error, (*pluginFunctions->setvalue)(&mNPP, NPNVprivateModeBool, &value), this, + NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO); return (error == NPERR_NO_ERROR) ? NS_OK : NS_ERROR_FAILURE; } static void PluginTimerCallback(nsITimer *aTimer, void *aClosure) { nsNPAPITimer* t = (nsNPAPITimer*)aClosure; NPP npp = t->npp;
--- a/dom/plugins/base/nsNPAPIPluginInstance.h +++ b/dom/plugins/base/nsNPAPIPluginInstance.h @@ -45,16 +45,28 @@ const NPDrawingModel kDefaultDrawingMode const NPDrawingModel kDefaultDrawingModel = NPDrawingModelQuickDraw; // Not supported #else const NPDrawingModel kDefaultDrawingModel = NPDrawingModelCoreGraphics; #endif #else const NPDrawingModel kDefaultDrawingModel = static_cast<NPDrawingModel>(0); #endif +/** + * Used to indicate whether it's OK to reenter Gecko and repaint, flush frames, + * run scripts, etc, during this plugin call. + * When NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO is set, we try to avoid dangerous + * Gecko activities when the plugin spins a nested event loop, on a best-effort + * basis. + */ +enum NSPluginCallReentry { + NS_PLUGIN_CALL_SAFE_TO_REENTER_GECKO, + NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO +}; + class nsNPAPITimer { public: NPP npp; uint32_t id; nsCOMPtr<nsITimer> timer; void (*callback)(NPP npp, uint32_t timerID); bool inCallback; @@ -268,22 +280,29 @@ public: // Called when the instance fails to instantiate beceause the Carbon // event model is not supported. void CarbonNPAPIFailure(); // 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() + static bool InPluginCallUnsafeForReentry() { return gInUnsafePluginCalls > 0; } + static void BeginPluginCall(NSPluginCallReentry aReentryState) { - NS_ASSERTION(InPluginCall(), "Must be in plugin call"); - --gInPluginCalls; + if (aReentryState == NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO) { + ++gInUnsafePluginCalls; + } + } + static void EndPluginCall(NSPluginCallReentry aReentryState) + { + if (aReentryState == NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO) { + NS_ASSERTION(gInUnsafePluginCalls > 0, "Must be in plugin call"); + --gInUnsafePluginCalls; + } } protected: nsresult GetTagType(nsPluginTagType *result); nsresult GetAttributes(uint16_t& n, const char*const*& names, const char*const*& values); nsresult GetParameters(uint16_t& n, const char*const*& names, @@ -371,12 +390,12 @@ private: bool mOnScreen; nsIntSize mCurrentSize; #endif // is this instance Java and affected by bug 750480? bool mHaveJavaC2PJSObjectQuirk; - static uint32_t gInPluginCalls; + static uint32_t gInUnsafePluginCalls; }; #endif // nsNPAPIPluginInstance_h_
--- a/dom/plugins/base/nsNPAPIPluginStreamListener.cpp +++ b/dom/plugins/base/nsNPAPIPluginStreamListener.cpp @@ -230,17 +230,18 @@ nsNPAPIPluginStreamListener::CleanUpStre NPP npp; mInst->GetNPP(&npp); if (mStreamStarted && pluginFunctions->destroystream) { NPPAutoPusher nppPusher(npp); NPError error; - NS_TRY_SAFE_CALL_RETURN(error, (*pluginFunctions->destroystream)(npp, &mNPStreamWrapper->mNPStream, reason), mInst); + NS_TRY_SAFE_CALL_RETURN(error, (*pluginFunctions->destroystream)(npp, &mNPStreamWrapper->mNPStream, reason), mInst, + NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO); NPP_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPP DestroyStream called: this=%p, npp=%p, reason=%d, return=%d, url=%s\n", this, npp, reason, error, mNPStreamWrapper->mNPStream.url)); if (error == NPERR_NO_ERROR) rv = NS_OK; } @@ -268,17 +269,18 @@ nsNPAPIPluginStreamListener::CallURLNoti return; NPPluginFuncs* pluginFunctions = plugin->PluginFuncs(); if (pluginFunctions->urlnotify) { NPP npp; mInst->GetNPP(&npp); - NS_TRY_SAFE_CALL_VOID((*pluginFunctions->urlnotify)(npp, mNotifyURL, reason, mNPStreamWrapper->mNPStream.notifyData), mInst); + NS_TRY_SAFE_CALL_VOID((*pluginFunctions->urlnotify)(npp, mNotifyURL, reason, mNPStreamWrapper->mNPStream.notifyData), mInst, + NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO); NPP_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPP URLNotify called: this=%p, npp=%p, notify=%p, reason=%d, url=%s\n", this, npp, mNPStreamWrapper->mNPStream.notifyData, reason, mNotifyURL)); } } nsresult @@ -316,17 +318,18 @@ nsNPAPIPluginStreamListener::OnStartBind mResponseHeaderBuf = PL_strdup(mResponseHeaders.get()); mNPStreamWrapper->mNPStream.headers = mResponseHeaderBuf; } mStreamListenerPeer = streamPeer; NPPAutoPusher nppPusher(npp); - NS_TRY_SAFE_CALL_RETURN(error, (*pluginFunctions->newstream)(npp, (char*)contentType, &mNPStreamWrapper->mNPStream, seekable, &streamType), mInst); + NS_TRY_SAFE_CALL_RETURN(error, (*pluginFunctions->newstream)(npp, (char*)contentType, &mNPStreamWrapper->mNPStream, seekable, &streamType), mInst, + NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO); NPP_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPP NewStream called: this=%p, npp=%p, mime=%s, seek=%d, type=%d, return=%d, url=%s\n", this, npp, (char *)contentType, seekable, streamType, error, mNPStreamWrapper->mNPStream.url)); if (error != NPERR_NO_ERROR) return NS_ERROR_FAILURE; @@ -558,17 +561,18 @@ nsNPAPIPluginStreamListener::OnDataAvail // mStreamBufferByteCount tells us how many bytes there are in the // buffer. WriteReady returns to us how many bytes the plugin is // ready to handle. while (mStreamBufferByteCount > 0) { int32_t numtowrite; if (pluginFunctions->writeready) { NPPAutoPusher nppPusher(npp); - NS_TRY_SAFE_CALL_RETURN(numtowrite, (*pluginFunctions->writeready)(npp, &mNPStreamWrapper->mNPStream), mInst); + NS_TRY_SAFE_CALL_RETURN(numtowrite, (*pluginFunctions->writeready)(npp, &mNPStreamWrapper->mNPStream), mInst, + NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO); NPP_PLUGIN_LOG(PLUGIN_LOG_NOISY, ("NPP WriteReady called: this=%p, npp=%p, " "return(towrite)=%d, url=%s\n", this, npp, numtowrite, mNPStreamWrapper->mNPStream.url)); if (!mStreamStarted) { // The plugin called NPN_DestroyStream() from within // NPP_WriteReady(), kill the stream. @@ -607,17 +611,18 @@ nsNPAPIPluginStreamListener::OnDataAvail // if WriteReady is not supported by the plugin, just write // the whole buffer numtowrite = mStreamBufferByteCount; } NPPAutoPusher nppPusher(npp); int32_t writeCount = 0; // bytes consumed by plugin instance - NS_TRY_SAFE_CALL_RETURN(writeCount, (*pluginFunctions->write)(npp, &mNPStreamWrapper->mNPStream, streamPosition, numtowrite, ptrStreamBuffer), mInst); + NS_TRY_SAFE_CALL_RETURN(writeCount, (*pluginFunctions->write)(npp, &mNPStreamWrapper->mNPStream, streamPosition, numtowrite, ptrStreamBuffer), mInst, + NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO); NPP_PLUGIN_LOG(PLUGIN_LOG_NOISY, ("NPP Write called: this=%p, npp=%p, pos=%d, len=%d, " "buf=%s, return(written)=%d, url=%s\n", this, npp, streamPosition, numtowrite, ptrStreamBuffer, writeCount, mNPStreamWrapper->mNPStream.url)); if (!mStreamStarted) { @@ -715,17 +720,18 @@ nsNPAPIPluginStreamListener::OnFileAvail NPPluginFuncs* pluginFunctions = plugin->PluginFuncs(); if (!pluginFunctions->asfile) return NS_ERROR_FAILURE; NPP npp; mInst->GetNPP(&npp); - NS_TRY_SAFE_CALL_VOID((*pluginFunctions->asfile)(npp, &mNPStreamWrapper->mNPStream, fileName), mInst); + NS_TRY_SAFE_CALL_VOID((*pluginFunctions->asfile)(npp, &mNPStreamWrapper->mNPStream, fileName), mInst, + NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO); NPP_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPP StreamAsFile called: this=%p, npp=%p, url=%s, file=%s\n", this, npp, mNPStreamWrapper->mNPStream.url, fileName)); return NS_OK; } @@ -857,17 +863,18 @@ nsNPAPIPluginStreamListener::HandleRedir if (NS_SUCCEEDED(uri->GetAsciiSpec(spec))) { // At this point the plugin will be responsible for making the callback // so save the callback object. mHTTPRedirectCallback = callback; NPP npp; mInst->GetNPP(&npp); #if defined(XP_WIN) || defined(XP_OS2) - NS_TRY_SAFE_CALL_VOID((*pluginFunctions->urlredirectnotify)(npp, spec.get(), static_cast<int32_t>(status), mNPStreamWrapper->mNPStream.notifyData), mInst); + NS_TRY_SAFE_CALL_VOID((*pluginFunctions->urlredirectnotify)(npp, spec.get(), static_cast<int32_t>(status), mNPStreamWrapper->mNPStream.notifyData), mInst, + NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO); #else MAIN_THREAD_JNI_REF_GUARD; (*pluginFunctions->urlredirectnotify)(npp, spec.get(), static_cast<int32_t>(status), mNPStreamWrapper->mNPStream.notifyData); #endif return true; } } }
--- a/dom/plugins/base/nsPluginNativeWindowOS2.cpp +++ b/dom/plugins/base/nsPluginNativeWindowOS2.cpp @@ -168,17 +168,18 @@ static bool ProcessFlashMessageDelayed(n MPARAM mp1, MPARAM mp2) { NS_ENSURE_TRUE(aWin, NS_ERROR_NULL_POINTER); NS_ENSURE_TRUE(aInst, NS_ERROR_NULL_POINTER); if (msg == sWM_FLASHBOUNCEMSG) { // See PluginWindowEvent::Run() below. NS_TRY_SAFE_CALL_VOID((aWin->GetWindowProc())(hWnd, WM_USER_FLASH, mp1, mp2), - inst); + inst, + NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO); return TRUE; } if (msg != WM_USER_FLASH) return false; // no need to delay // do stuff nsCOMPtr<nsIRunnable> pwe = aWin->GetPluginWindowEvent(hWnd, msg, mp1, mp2); @@ -304,19 +305,21 @@ static MRESULT EXPENTRY PluginWndProc(HW uint16_t apiVersion; if (NS_SUCCEEDED(inst->GetPluginAPIVersion(&apiVersion)) && !versionOK(apiVersion, NP_POPUP_API_VERSION)) inst->PushPopupsEnabledState(true); } MRESULT res = (MRESULT)TRUE; if (win->mPluginType == nsPluginType_Java_vm) - NS_TRY_SAFE_CALL_RETURN(res, ::WinDefWindowProc(hWnd, msg, mp1, mp2), inst); + NS_TRY_SAFE_CALL_RETURN(res, ::WinDefWindowProc(hWnd, msg, mp1, mp2), inst, + NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO); else - NS_TRY_SAFE_CALL_RETURN(res, (win->GetWindowProc())(hWnd, msg, mp1, mp2), inst); + NS_TRY_SAFE_CALL_RETURN(res, (win->GetWindowProc())(hWnd, msg, mp1, mp2), inst, + NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO); if (inst) { // Popups are enabled (were enabled before the call to // CallWindowProc()). Some plugins (at least the flash player) // post messages from their key handlers etc that delay the actual // processing, so we need to delay the disabling of popups so that // popups remain enabled when the flash player ends up processing // the actual key handlers. We do this by posting an event that @@ -392,17 +395,18 @@ NS_IMETHODIMP PluginWindowEvent::Run() // XXX Unwind issues related to runnable event callback depth for this // event and destruction of the plugin. (Bug 493601) ::WinPostMsg(hWnd, sWM_FLASHBOUNCEMSG, GetWParam(), GetLParam()); else // Currently not used, but added so that processing events here // is more generic. NS_TRY_SAFE_CALL_VOID((win->GetWindowProc()) (hWnd, GetMsg(), GetWParam(), GetLParam()), - inst); + inst, + NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO); Clear(); return NS_OK; } PluginWindowEvent* nsPluginNativeWindowOS2::GetPluginWindowEvent(HWND aWnd, ULONG aMsg, MPARAM aMp1, MPARAM aMp2) {
--- a/dom/plugins/base/nsPluginSafety.h +++ b/dom/plugins/base/nsPluginSafety.h @@ -13,28 +13,28 @@ #ifdef MOZ_WIDGET_ANDROID #include "AndroidBridge.h" #define MAIN_THREAD_JNI_REF_GUARD mozilla::AutoLocalJNIFrame jniFrame #else #define MAIN_THREAD_JNI_REF_GUARD #endif -PRIntervalTime NS_NotifyBeginPluginCall(); -void NS_NotifyPluginCall(PRIntervalTime); +PRIntervalTime NS_NotifyBeginPluginCall(NSPluginCallReentry aReentryState); +void NS_NotifyPluginCall(PRIntervalTime aTime, NSPluginCallReentry aReentryState); -#define NS_TRY_SAFE_CALL_RETURN(ret, fun, pluginInst) \ +#define NS_TRY_SAFE_CALL_RETURN(ret, fun, pluginInst, pluginCallReentry) \ PR_BEGIN_MACRO \ MAIN_THREAD_JNI_REF_GUARD; \ - PRIntervalTime startTime = NS_NotifyBeginPluginCall(); \ + PRIntervalTime startTime = NS_NotifyBeginPluginCall(pluginCallReentry); \ ret = fun; \ - NS_NotifyPluginCall(startTime); \ + NS_NotifyPluginCall(startTime, pluginCallReentry); \ PR_END_MACRO -#define NS_TRY_SAFE_CALL_VOID(fun, pluginInst) \ +#define NS_TRY_SAFE_CALL_VOID(fun, pluginInst, pluginCallReentry) \ PR_BEGIN_MACRO \ MAIN_THREAD_JNI_REF_GUARD; \ - PRIntervalTime startTime = NS_NotifyBeginPluginCall(); \ + PRIntervalTime startTime = NS_NotifyBeginPluginCall(pluginCallReentry); \ fun; \ - NS_NotifyPluginCall(startTime); \ + NS_NotifyPluginCall(startTime, pluginCallReentry); \ PR_END_MACRO #endif //nsPluginSafety_h_
--- a/layout/base/nsRefreshDriver.cpp +++ b/layout/base/nsRefreshDriver.cpp @@ -815,17 +815,17 @@ nsRefreshDriver::DoTick() } void nsRefreshDriver::Tick(int64_t aNowEpoch, TimeStamp aNowTime) { NS_PRECONDITION(!nsContentUtils::GetCurrentJSContext(), "Shouldn't have a JSContext on the stack"); - if (nsNPAPIPluginInstance::InPluginCall()) { + if (nsNPAPIPluginInstance::InPluginCallUnsafeForReentry()) { NS_ERROR("Refresh driver should not run during plugin call!"); // Try to survive this by just ignoring the refresh tick. return; } SAMPLE_LABEL("nsRefreshDriver", "Tick"); // We're either frozen or we were disconnected (likely in the middle
--- a/layout/generic/nsObjectFrame.cpp +++ b/layout/generic/nsObjectFrame.cpp @@ -2066,30 +2066,34 @@ nsObjectFrame::HandleEvent(nsPresContext mInstanceOwner->ContentsScaleFactorChanged(scaleFactor); return NS_OK; } #endif if (mInstanceOwner->SendNativeEvents() && NS_IS_PLUGIN_EVENT(anEvent)) { *anEventStatus = mInstanceOwner->ProcessEvent(*anEvent); + // Due to plugin code reentering Gecko, this frame may be dead at this + // point. return rv; } #ifdef XP_WIN rv = nsObjectFrameSuper::HandleEvent(aPresContext, anEvent, anEventStatus); return rv; #endif #ifdef XP_MACOSX // we want to process some native mouse events in the cocoa event model if ((anEvent->message == NS_MOUSE_ENTER || anEvent->message == NS_WHEEL_WHEEL) && mInstanceOwner->GetEventModel() == NPEventModelCocoa) { *anEventStatus = mInstanceOwner->ProcessEvent(*anEvent); + // Due to plugin code reentering Gecko, this frame may be dead at this + // point. return rv; } #endif return nsObjectFrameSuper::HandleEvent(aPresContext, anEvent, anEventStatus); } #ifdef XP_MACOSX