mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 03:15:11 +00:00
bug 1212906 - don't handle windows messages while waiting for a sync a11y ipc message r=billm
Windows messages can trigger sync ipc messages to the child process. That means if we handle windows messages while waiting for the response to a sync a11y ipc message we can end up reentering the code to send ipc messages which is bad. Try and avoid this situation by not handling windows messages while waiting for a sync a11y message.
This commit is contained in:
parent
e8d8cb32c6
commit
dda4730c3c
@ -24,6 +24,7 @@
|
||||
|
||||
#include <set>
|
||||
|
||||
#include "mozilla/a11y/PDocAccessible.h"
|
||||
#include "AppProcessChecker.h"
|
||||
#include "AudioChannelService.h"
|
||||
#include "BlobParent.h"
|
||||
@ -5476,3 +5477,19 @@ ParentIdleListener::Observe(nsISupports*, const char* aTopic, const char16_t* aD
|
||||
nsDependentString(aData));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentParent::HandleWindowsMessages(const Message& aMsg) const
|
||||
{
|
||||
MOZ_ASSERT(aMsg.is_sync());
|
||||
|
||||
// a11y messages can be triggered by windows messages, which means if we
|
||||
// allow handling windows messages while we wait for the response to a sync
|
||||
// a11y message we can reenter the ipc message sending code.
|
||||
if (a11y::PDocAccessible::PDocAccessibleStart < aMsg.type() &&
|
||||
a11y::PDocAccessible::PDocAccessibleEnd > aMsg.type()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -427,6 +427,8 @@ public:
|
||||
virtual bool
|
||||
DeallocPContentPermissionRequestParent(PContentPermissionRequestParent* actor) override;
|
||||
|
||||
virtual bool HandleWindowsMessages(const Message& aMsg) const override;
|
||||
|
||||
bool HasGamepadListener() const { return mHasGamepadListener; }
|
||||
|
||||
void SetNuwaParent(NuwaParent* aNuwaParent) { mNuwaParent = aNuwaParent; }
|
||||
|
@ -922,6 +922,7 @@ MessageChannel::Send(Message* aMsg, Message* aReply)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool handleWindowsMessages = mListener->HandleWindowsMessages(*aMsg);
|
||||
mLink->SendMessage(msg.forget());
|
||||
|
||||
while (true) {
|
||||
@ -942,7 +943,7 @@ MessageChannel::Send(Message* aMsg, Message* aReply)
|
||||
|
||||
MOZ_ASSERT(!mTimedOutMessageSeqno);
|
||||
|
||||
bool maybeTimedOut = !WaitForSyncNotify();
|
||||
bool maybeTimedOut = !WaitForSyncNotify(handleWindowsMessages);
|
||||
|
||||
if (!Connected()) {
|
||||
ReportConnectionError("MessageChannel::SendAndWait");
|
||||
@ -1576,7 +1577,7 @@ MessageChannel::WaitResponse(bool aWaitTimedOut)
|
||||
|
||||
#ifndef OS_WIN
|
||||
bool
|
||||
MessageChannel::WaitForSyncNotify()
|
||||
MessageChannel::WaitForSyncNotify(bool /* aHandleWindowsMessages */)
|
||||
{
|
||||
PRIntervalTime timeout = (kNoTimeout == mTimeoutMs) ?
|
||||
PR_INTERVAL_NO_TIMEOUT :
|
||||
@ -1594,7 +1595,7 @@ MessageChannel::WaitForSyncNotify()
|
||||
bool
|
||||
MessageChannel::WaitForInterruptNotify()
|
||||
{
|
||||
return WaitForSyncNotify();
|
||||
return WaitForSyncNotify(true);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -278,7 +278,7 @@ class MessageChannel : HasResultCodes
|
||||
//
|
||||
// So in sum: true is a meaningful return value; false isn't,
|
||||
// necessarily.
|
||||
bool WaitForSyncNotify();
|
||||
bool WaitForSyncNotify(bool aHandleWindowsMessages);
|
||||
bool WaitForInterruptNotify();
|
||||
|
||||
bool WaitResponse(bool aWaitTimedOut);
|
||||
|
@ -98,6 +98,12 @@ class MessageListener
|
||||
return RIPChildWins;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if windows messages can be handled while waiting for a reply
|
||||
* to a sync IPDL message.
|
||||
*/
|
||||
virtual bool HandleWindowsMessages(const Message& aMsg) const { return true; }
|
||||
|
||||
virtual void OnEnteredSyncSend() {
|
||||
}
|
||||
virtual void OnExitedSyncSend() {
|
||||
|
@ -944,7 +944,7 @@ DeneuteredWindowRegion::~DeneuteredWindowRegion()
|
||||
}
|
||||
|
||||
bool
|
||||
MessageChannel::WaitForSyncNotify()
|
||||
MessageChannel::WaitForSyncNotify(bool aHandleWindowsMessages)
|
||||
{
|
||||
mMonitor->AssertCurrentThreadOwns();
|
||||
|
||||
@ -952,7 +952,7 @@ MessageChannel::WaitForSyncNotify()
|
||||
|
||||
// Use a blocking wait if this channel does not require
|
||||
// Windows message deferral behavior.
|
||||
if (!(mFlags & REQUIRE_DEFERRED_MESSAGE_PROTECTION)) {
|
||||
if (!(mFlags & REQUIRE_DEFERRED_MESSAGE_PROTECTION) || !aHandleWindowsMessages) {
|
||||
PRIntervalTime timeout = (kNoTimeout == mTimeoutMs) ?
|
||||
PR_INTERVAL_NO_TIMEOUT :
|
||||
PR_MillisecondsToInterval(mTimeoutMs);
|
||||
@ -1088,7 +1088,7 @@ MessageChannel::WaitForInterruptNotify()
|
||||
// Re-use sync notification wait code if this channel does not require
|
||||
// Windows message deferral behavior.
|
||||
if (!(mFlags & REQUIRE_DEFERRED_MESSAGE_PROTECTION)) {
|
||||
return WaitForSyncNotify();
|
||||
return WaitForSyncNotify(true);
|
||||
}
|
||||
|
||||
if (!InterruptStackDepth() && !AwaitingIncomingMessage()) {
|
||||
|
Loading…
Reference in New Issue
Block a user