mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 07:13:20 +00:00
Bug 998863: Asynchronous Plugin Initialization, Part 3: ipc/glue changes; r=dvander
This commit is contained in:
parent
15edf3ffa5
commit
fc2f0c6a2e
@ -298,6 +298,7 @@ MessageChannel::MessageChannel(MessageListener *aListener)
|
||||
mRecvdErrors(0),
|
||||
mRemoteStackDepthGuess(false),
|
||||
mSawInterruptOutMsg(false),
|
||||
mIsWaitingForIncoming(false),
|
||||
mAbortOnError(false),
|
||||
mBlockScripts(false),
|
||||
mFlags(REQUIRE_DEFAULT),
|
||||
@ -664,7 +665,8 @@ MessageChannel::OnMessageReceivedFromLink(const Message& aMsg)
|
||||
}
|
||||
|
||||
bool shouldWakeUp = AwaitingInterruptReply() ||
|
||||
(AwaitingSyncReply() && !ShouldDeferMessage(aMsg));
|
||||
(AwaitingSyncReply() && !ShouldDeferMessage(aMsg)) ||
|
||||
AwaitingIncomingMessage();
|
||||
|
||||
// There are three cases we're concerned about, relating to the state of the
|
||||
// main thread:
|
||||
@ -987,6 +989,35 @@ MessageChannel::Call(Message* aMsg, Message* aReply)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
MessageChannel::WaitForIncomingMessage()
|
||||
{
|
||||
#ifdef OS_WIN
|
||||
SyncStackFrame frame(this, true);
|
||||
#endif
|
||||
|
||||
{ // Scope for lock
|
||||
MonitorAutoLock lock(*mMonitor);
|
||||
AutoEnterWaitForIncoming waitingForIncoming(*this);
|
||||
if (mChannelState != ChannelConnected) {
|
||||
return false;
|
||||
}
|
||||
if (!HasPendingEvents()) {
|
||||
return WaitForInterruptNotify();
|
||||
}
|
||||
}
|
||||
|
||||
return OnMaybeDequeueOne();
|
||||
}
|
||||
|
||||
bool
|
||||
MessageChannel::HasPendingEvents()
|
||||
{
|
||||
AssertWorkerThread();
|
||||
mMonitor->AssertCurrentThreadOwns();
|
||||
return Connected() && !mPending.empty();
|
||||
}
|
||||
|
||||
bool
|
||||
MessageChannel::InterruptEventOccurred()
|
||||
{
|
||||
@ -1546,7 +1577,7 @@ MessageChannel::OnChannelErrorFromLink()
|
||||
if (InterruptStackDepth() > 0)
|
||||
NotifyWorkerThread();
|
||||
|
||||
if (AwaitingSyncReply())
|
||||
if (AwaitingSyncReply() || AwaitingIncomingMessage())
|
||||
NotifyWorkerThread();
|
||||
|
||||
if (ChannelClosing != mChannelState) {
|
||||
|
@ -124,6 +124,9 @@ class MessageChannel : HasResultCodes
|
||||
// Make an Interrupt call to the other side of the channel
|
||||
bool Call(Message* aMsg, Message* aReply);
|
||||
|
||||
// Wait until a message is received
|
||||
bool WaitForIncomingMessage();
|
||||
|
||||
bool CanSend() const;
|
||||
|
||||
void SetReplyTimeoutMs(int32_t aTimeoutMs);
|
||||
@ -214,6 +217,7 @@ class MessageChannel : HasResultCodes
|
||||
void DispatchOnChannelConnected();
|
||||
|
||||
bool InterruptEventOccurred();
|
||||
bool HasPendingEvents();
|
||||
|
||||
bool ProcessPendingRequest(const Message &aUrgent);
|
||||
|
||||
@ -319,6 +323,30 @@ class MessageChannel : HasResultCodes
|
||||
mMonitor->AssertCurrentThreadOwns();
|
||||
return !mInterruptStack.empty();
|
||||
}
|
||||
bool AwaitingIncomingMessage() const {
|
||||
mMonitor->AssertCurrentThreadOwns();
|
||||
return mIsWaitingForIncoming;
|
||||
}
|
||||
|
||||
class MOZ_STACK_CLASS AutoEnterWaitForIncoming
|
||||
{
|
||||
public:
|
||||
explicit AutoEnterWaitForIncoming(MessageChannel& aChannel)
|
||||
: mChannel(aChannel)
|
||||
{
|
||||
aChannel.mMonitor->AssertCurrentThreadOwns();
|
||||
aChannel.mIsWaitingForIncoming = true;
|
||||
}
|
||||
|
||||
~AutoEnterWaitForIncoming()
|
||||
{
|
||||
mChannel.mIsWaitingForIncoming = false;
|
||||
}
|
||||
|
||||
private:
|
||||
MessageChannel& mChannel;
|
||||
};
|
||||
friend class AutoEnterWaitForIncoming;
|
||||
|
||||
// Returns true if we're dispatching a sync message's callback.
|
||||
bool DispatchingSyncMessage() const {
|
||||
@ -639,6 +667,11 @@ class MessageChannel : HasResultCodes
|
||||
// ExitedCxxStack(), from which this variable is reset.
|
||||
bool mSawInterruptOutMsg;
|
||||
|
||||
// Are we waiting on this channel for an incoming message? This is used
|
||||
// to implement WaitForIncomingMessage(). Must only be accessed while owning
|
||||
// mMonitor.
|
||||
bool mIsWaitingForIncoming;
|
||||
|
||||
// Map of replies received "out of turn", because of Interrupt
|
||||
// in-calls racing with replies to outstanding in-calls. See
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=521929.
|
||||
|
@ -966,7 +966,7 @@ MessageChannel::WaitForInterruptNotify()
|
||||
return WaitForSyncNotify();
|
||||
}
|
||||
|
||||
if (!InterruptStackDepth()) {
|
||||
if (!InterruptStackDepth() && !AwaitingIncomingMessage()) {
|
||||
// There is currently no way to recover from this condition.
|
||||
NS_RUNTIMEABORT("StackDepth() is 0 in call to MessageChannel::WaitForNotify!");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user