зеркало из https://github.com/mozilla/gecko-dev.git
Bug 950745 - Flag when we're processing urgent messages and disallow certain activities (r=bsmedberg,luke)
This commit is contained in:
Родитель
0d0f9abef2
Коммит
024b67429e
|
@ -25,6 +25,7 @@
|
|||
#include "mozilla/EventDispatcher.h"
|
||||
#include "mozilla/EventListenerManager.h"
|
||||
#include "mozilla/InternalMutationEvent.h"
|
||||
#include "mozilla/ipc/MessageChannel.h"
|
||||
#include "mozilla/MiscEvents.h"
|
||||
#include "mozilla/MouseEvents.h"
|
||||
#include "mozilla/TextEvents.h"
|
||||
|
@ -400,6 +401,10 @@ EventDispatcher::Dispatch(nsISupports* aTarget,
|
|||
NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
NS_ASSERTION(!aTargets || !aEvent->message, "Wrong parameters!");
|
||||
|
||||
#ifdef NIGHTLY_BUILD
|
||||
MOZ_RELEASE_ASSERT(!mozilla::ipc::ProcessingUrgentMessages());
|
||||
#endif
|
||||
|
||||
// If we're dispatching an already created DOMEvent object, make
|
||||
// sure it is initialized!
|
||||
// If aTargets is non-null, the event isn't going to be dispatched.
|
||||
|
|
|
@ -36,6 +36,8 @@ struct RunnableMethodTraits<mozilla::ipc::MessageChannel>
|
|||
DebugAbort(__FILE__, __LINE__, #_cond,## __VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
static uintptr_t gDispatchingUrgentMessageCount;
|
||||
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
|
||||
|
@ -1099,9 +1101,13 @@ MessageChannel::DispatchUrgentMessage(const Message& aMsg)
|
|||
|
||||
Message *reply = nullptr;
|
||||
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
gDispatchingUrgentMessageCount++;
|
||||
mDispatchingUrgentMessageCount++;
|
||||
Result rv = mListener->OnCallReceived(aMsg, reply);
|
||||
mDispatchingUrgentMessageCount--;
|
||||
gDispatchingUrgentMessageCount--;
|
||||
|
||||
if (!MaybeHandleError(rv, "DispatchUrgentMessage")) {
|
||||
delete reply;
|
||||
|
@ -1752,5 +1758,11 @@ MessageChannel::DumpInterruptStack(const char* const pfx) const
|
|||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ProcessingUrgentMessages()
|
||||
{
|
||||
return gDispatchingUrgentMessageCount > 0;
|
||||
}
|
||||
|
||||
} // ipc
|
||||
} // mozilla
|
||||
|
|
|
@ -641,6 +641,9 @@ class MessageChannel : HasResultCodes
|
|||
bool mAbortOnError;
|
||||
};
|
||||
|
||||
bool
|
||||
ProcessingUrgentMessages();
|
||||
|
||||
} // namespace ipc
|
||||
} // namespace mozilla
|
||||
|
||||
|
|
|
@ -8,10 +8,12 @@
|
|||
#include "JavaScriptChild.h"
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/ipc/MessageChannel.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "xpcprivate.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "nsCxPusher.h"
|
||||
#include "AccessCheck.h"
|
||||
|
||||
using namespace JS;
|
||||
using namespace mozilla;
|
||||
|
@ -19,6 +21,17 @@ using namespace mozilla::jsipc;
|
|||
|
||||
using mozilla::AutoSafeJSContext;
|
||||
|
||||
#ifdef NIGHTLY_BUILD
|
||||
static void
|
||||
UrgentMessageCheck(JSContext *cx, HandleScript script)
|
||||
{
|
||||
// We're only allowed to enter chrome JS code while processing urgent
|
||||
// messages.
|
||||
if (ipc::ProcessingUrgentMessages())
|
||||
MOZ_RELEASE_ASSERT(xpc::AccessCheck::isChrome(js::GetContextCompartment(cx)));
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
FinalizeChild(JSFreeOp *fop, JSFinalizeStatus status, bool isCompartment, void *data)
|
||||
{
|
||||
|
@ -31,6 +44,9 @@ JavaScriptChild::JavaScriptChild(JSRuntime *rt)
|
|||
: JavaScriptShared(rt),
|
||||
JavaScriptBase<PJavaScriptChild>(rt)
|
||||
{
|
||||
#ifdef NIGHTLY_BUILD
|
||||
js::SetAssertOnScriptEntryHook(rt, UrgentMessageCheck);
|
||||
#endif
|
||||
}
|
||||
|
||||
JavaScriptChild::~JavaScriptChild()
|
||||
|
|
|
@ -30,5 +30,6 @@ LOCAL_INCLUDES += [
|
|||
'/js/ipc',
|
||||
'/js/public',
|
||||
'/js/xpconnect/src',
|
||||
'/js/xpconnect/wrappers',
|
||||
]
|
||||
|
||||
|
|
|
@ -63,6 +63,14 @@ js::ForgetSourceHook(JSRuntime *rt)
|
|||
return Move(rt->sourceHook);
|
||||
}
|
||||
|
||||
#ifdef NIGHTLY_BUILD
|
||||
JS_FRIEND_API(void)
|
||||
js::SetAssertOnScriptEntryHook(JSRuntime *rt, AssertOnScriptEntryHook hook)
|
||||
{
|
||||
rt->assertOnScriptEntryHook_ = hook;
|
||||
}
|
||||
#endif
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
JS_SetGrayGCRootsTracer(JSRuntime *rt, JSTraceDataOp traceOp, void *data)
|
||||
{
|
||||
|
|
|
@ -422,6 +422,13 @@ SetSourceHook(JSRuntime *rt, mozilla::UniquePtr<SourceHook> hook);
|
|||
extern JS_FRIEND_API(mozilla::UniquePtr<SourceHook>)
|
||||
ForgetSourceHook(JSRuntime *rt);
|
||||
|
||||
#ifdef NIGHTLY_BUILD
|
||||
typedef void (*AssertOnScriptEntryHook)(JSContext *cx, JS::HandleScript script);
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
SetAssertOnScriptEntryHook(JSRuntime *rt, AssertOnScriptEntryHook hook);
|
||||
#endif
|
||||
|
||||
extern JS_FRIEND_API(JS::Zone *)
|
||||
GetCompartmentZone(JSCompartment *comp);
|
||||
|
||||
|
|
|
@ -374,6 +374,11 @@ js::RunScript(JSContext *cx, RunState &state)
|
|||
{
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
|
||||
#ifdef NIGHTLY_BUILD
|
||||
if (AssertOnScriptEntryHook hook = cx->runtime()->assertOnScriptEntryHook_)
|
||||
(*hook)(cx, state.script());
|
||||
#endif
|
||||
|
||||
SPSEntryMarker marker(cx->runtime(), state.script());
|
||||
|
||||
state.script()->ensureNonLazyCanonicalFunction(cx);
|
||||
|
|
|
@ -203,7 +203,7 @@ class RunState
|
|||
return (GeneratorState *)this;
|
||||
}
|
||||
|
||||
JSScript *script() const { return script_; }
|
||||
JS::HandleScript script() const { return script_; }
|
||||
|
||||
virtual InterpreterFrame *pushInterpreterFrame(JSContext *cx) = 0;
|
||||
virtual void setReturnValue(Value v) = 0;
|
||||
|
|
|
@ -172,6 +172,9 @@ JSRuntime::JSRuntime(JSRuntime *parentRuntime)
|
|||
negativeInfinityValue(DoubleValue(NegativeInfinity<double>())),
|
||||
positiveInfinityValue(DoubleValue(PositiveInfinity<double>())),
|
||||
emptyString(nullptr),
|
||||
#ifdef NIGHTLY_BUILD
|
||||
assertOnScriptEntryHook_(nullptr),
|
||||
#endif
|
||||
debugMode(false),
|
||||
spsProfiler(thisFromCtor()),
|
||||
profilingScripts(false),
|
||||
|
|
|
@ -993,6 +993,10 @@ struct JSRuntime : public JS::shadow::Runtime,
|
|||
|
||||
mozilla::UniquePtr<js::SourceHook> sourceHook;
|
||||
|
||||
#ifdef NIGHTLY_BUILD
|
||||
js::AssertOnScriptEntryHook assertOnScriptEntryHook_;
|
||||
#endif
|
||||
|
||||
/* If true, new compartments are initially in debug mode. */
|
||||
bool debugMode;
|
||||
|
||||
|
|
|
@ -4341,6 +4341,8 @@ inline static mozilla::HangMonitor::ActivityType ActivityTypeForMessage(UINT msg
|
|||
// and http://msdn.microsoft.com/en-us/library/ms633573%28VS.85%29.aspx
|
||||
LRESULT CALLBACK nsWindow::WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(!ipc::ProcessingUrgentMessages());
|
||||
|
||||
HangMonitor::NotifyActivity(ActivityTypeForMessage(msg));
|
||||
|
||||
return mozilla::CallWindowProcCrashProtected(WindowProcInternal, hWnd, msg, wParam, lParam);
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "nsIObserverService.h"
|
||||
#include "mozilla/HangMonitor.h"
|
||||
#include "mozilla/IOInterposer.h"
|
||||
#include "mozilla/ipc/MessageChannel.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "nsXPCOMPrivate.h"
|
||||
#include "mozilla/ChaosMode.h"
|
||||
|
@ -686,6 +687,9 @@ nsThread::ProcessNextEvent(bool aMayWait, bool* aResult)
|
|||
{
|
||||
LOG(("THRD(%p) ProcessNextEvent [%u %u]\n", this, aMayWait, mRunningEvent));
|
||||
|
||||
// If we're on the main thread, we shouldn't be dispatching CPOWs.
|
||||
MOZ_RELEASE_ASSERT(mIsMainThread != MAIN_THREAD || !ipc::ProcessingUrgentMessages());
|
||||
|
||||
if (NS_WARN_IF(PR_GetCurrentThread() != mThread)) {
|
||||
return NS_ERROR_NOT_SAME_THREAD;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче