зеркало из https://github.com/mozilla/gecko-dev.git
Merge inbound to m-c. a=merge
This commit is contained in:
Коммит
81292f7f5e
|
@ -2471,6 +2471,32 @@ SourceMediaStream::NotifyDirectConsumers(TrackData *aTrack,
|
|||
}
|
||||
}
|
||||
|
||||
// These handle notifying all the listeners of an event
|
||||
void
|
||||
SourceMediaStream::NotifyListenersEventImpl(MediaStreamListener::MediaStreamGraphEvent aEvent)
|
||||
{
|
||||
for (uint32_t j = 0; j < mListeners.Length(); ++j) {
|
||||
MediaStreamListener* l = mListeners[j];
|
||||
l->NotifyEvent(GraphImpl(), aEvent);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SourceMediaStream::NotifyListenersEvent(MediaStreamListener::MediaStreamGraphEvent aNewEvent)
|
||||
{
|
||||
class Message : public ControlMessage {
|
||||
public:
|
||||
Message(SourceMediaStream* aStream, MediaStreamListener::MediaStreamGraphEvent aEvent) :
|
||||
ControlMessage(aStream), mEvent(aEvent) {}
|
||||
virtual void Run()
|
||||
{
|
||||
mStream->AsSourceStream()->NotifyListenersEventImpl(mEvent);
|
||||
}
|
||||
MediaStreamListener::MediaStreamGraphEvent mEvent;
|
||||
};
|
||||
GraphImpl()->AppendMessage(new Message(this, aNewEvent));
|
||||
}
|
||||
|
||||
void
|
||||
SourceMediaStream::AddDirectListener(MediaStreamDirectListener* aListener)
|
||||
{
|
||||
|
@ -2482,10 +2508,8 @@ SourceMediaStream::AddDirectListener(MediaStreamDirectListener* aListener)
|
|||
}
|
||||
|
||||
if (wasEmpty) {
|
||||
for (uint32_t j = 0; j < mListeners.Length(); ++j) {
|
||||
MediaStreamListener* l = mListeners[j];
|
||||
l->NotifyEvent(GraphImpl(), MediaStreamListener::EVENT_HAS_DIRECT_LISTENERS);
|
||||
}
|
||||
// Async
|
||||
NotifyListenersEvent(MediaStreamListener::EVENT_HAS_DIRECT_LISTENERS);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2500,10 +2524,8 @@ SourceMediaStream::RemoveDirectListener(MediaStreamDirectListener* aListener)
|
|||
}
|
||||
|
||||
if (isEmpty) {
|
||||
for (uint32_t j = 0; j < mListeners.Length(); ++j) {
|
||||
MediaStreamListener* l = mListeners[j];
|
||||
l->NotifyEvent(GraphImpl(), MediaStreamListener::EVENT_HAS_NO_DIRECT_LISTENERS);
|
||||
}
|
||||
// Async
|
||||
NotifyListenersEvent(MediaStreamListener::EVENT_HAS_NO_DIRECT_LISTENERS);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -716,6 +716,13 @@ public:
|
|||
*/
|
||||
void SetPullEnabled(bool aEnabled);
|
||||
|
||||
/**
|
||||
* These add/remove DirectListeners, which allow bypassing the graph and any
|
||||
* synchronization delays for e.g. PeerConnection, which wants the data ASAP
|
||||
* and lets the far-end handle sync and playout timing.
|
||||
*/
|
||||
void NotifyListenersEventImpl(MediaStreamListener::MediaStreamGraphEvent aEvent);
|
||||
void NotifyListenersEvent(MediaStreamListener::MediaStreamGraphEvent aEvent);
|
||||
void AddDirectListener(MediaStreamDirectListener* aListener);
|
||||
void RemoveDirectListener(MediaStreamDirectListener* aListener);
|
||||
|
||||
|
|
|
@ -143,6 +143,11 @@ PluginModuleChild::Init(const std::string& aPluginFilename,
|
|||
|
||||
GetIPCChannel()->SetAbortOnError(true);
|
||||
|
||||
// Request Windows message deferral behavior on our channel. This
|
||||
// applies to the top level and all sub plugin protocols since they
|
||||
// all share the same channel.
|
||||
GetIPCChannel()->SetChannelFlags(MessageChannel::REQUIRE_DEFERRED_MESSAGE_PROTECTION);
|
||||
|
||||
#ifdef XP_WIN
|
||||
COMMessageFilter::Initialize(this);
|
||||
#endif
|
||||
|
|
|
@ -103,6 +103,11 @@ PluginModuleParent::LoadModule(const char* aFilePath)
|
|||
parent->Open(parent->mSubprocess->GetChannel(),
|
||||
parent->mSubprocess->GetChildProcessHandle());
|
||||
|
||||
// Request Windows message deferral behavior on our channel. This
|
||||
// applies to the top level and all sub plugin protocols since they
|
||||
// all share the same channel.
|
||||
parent->GetIPCChannel()->SetChannelFlags(MessageChannel::REQUIRE_DEFERRED_MESSAGE_PROTECTION);
|
||||
|
||||
TimeoutChanged(CHILD_TIMEOUT_PREF, parent);
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
|
|
|
@ -234,7 +234,8 @@ MessageChannel::MessageChannel(MessageListener *aListener)
|
|||
mRemoteStackDepthGuess(false),
|
||||
mSawInterruptOutMsg(false),
|
||||
mAbortOnError(false),
|
||||
mBlockScripts(false)
|
||||
mBlockScripts(false),
|
||||
mFlags(REQUIRE_DEFAULT)
|
||||
{
|
||||
MOZ_COUNT_CTOR(ipc::MessageChannel);
|
||||
|
||||
|
|
|
@ -63,13 +63,13 @@ class MessageChannel : HasResultCodes
|
|||
// "Open" from the perspective of the transport layer; the underlying
|
||||
// socketpair/pipe should already be created.
|
||||
//
|
||||
// Returns true iff the transport layer was successfully connected,
|
||||
// Returns true if the transport layer was successfully connected,
|
||||
// i.e., mChannelState == ChannelConnected.
|
||||
bool Open(Transport* aTransport, MessageLoop* aIOLoop=0, Side aSide=UnknownSide);
|
||||
|
||||
// "Open" a connection to another thread in the same process.
|
||||
//
|
||||
// Returns true iff the transport layer was successfully connected,
|
||||
// Returns true if the transport layer was successfully connected,
|
||||
// i.e., mChannelState == ChannelConnected.
|
||||
//
|
||||
// For more details on the process of opening a channel between
|
||||
|
@ -89,6 +89,19 @@ class MessageChannel : HasResultCodes
|
|||
mAbortOnError = true;
|
||||
}
|
||||
|
||||
// Misc. behavioral traits consumers can request for this channel
|
||||
enum ChannelFlags {
|
||||
REQUIRE_DEFAULT = 0,
|
||||
// Windows: if this channel operates on the UI thread, indicates
|
||||
// WindowsMessageLoop code should enable deferred native message
|
||||
// handling to prevent deadlocks. Should only be used for protocols
|
||||
// that manage child processes which might create native UI, like
|
||||
// plugins.
|
||||
REQUIRE_DEFERRED_MESSAGE_PROTECTION = 1 << 0
|
||||
};
|
||||
void SetChannelFlags(ChannelFlags aFlags) { mFlags = aFlags; }
|
||||
ChannelFlags GetChannelFlags() { return mFlags; }
|
||||
|
||||
void BlockScripts();
|
||||
|
||||
bool ShouldBlockScripts() const
|
||||
|
@ -649,6 +662,9 @@ class MessageChannel : HasResultCodes
|
|||
|
||||
// Should we prevent scripts from running while dispatching urgent messages?
|
||||
bool mBlockScripts;
|
||||
|
||||
// See SetChannelFlags
|
||||
ChannelFlags mFlags;
|
||||
};
|
||||
|
||||
bool
|
||||
|
|
|
@ -657,6 +657,7 @@ InitUIThread()
|
|||
} // namespace ipc
|
||||
} // namespace mozilla
|
||||
|
||||
// See SpinInternalEventLoop below
|
||||
MessageChannel::SyncStackFrame::SyncStackFrame(MessageChannel* channel, bool interrupt)
|
||||
: mInterrupt(interrupt)
|
||||
, mSpinNestedEvents(false)
|
||||
|
@ -665,8 +666,9 @@ MessageChannel::SyncStackFrame::SyncStackFrame(MessageChannel* channel, bool int
|
|||
, mPrev(mChannel->mTopFrame)
|
||||
, mStaticPrev(sStaticTopFrame)
|
||||
{
|
||||
// Only track stack frames when we are on the gui thread.
|
||||
if (GetCurrentThreadId() != gUIThreadId) {
|
||||
// Only track stack frames when Windows message deferral behavior
|
||||
// is request for the channel.
|
||||
if (!(mChannel->GetChannelFlags() & REQUIRE_DEFERRED_MESSAGE_PROTECTION)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -682,7 +684,7 @@ MessageChannel::SyncStackFrame::SyncStackFrame(MessageChannel* channel, bool int
|
|||
|
||||
MessageChannel::SyncStackFrame::~SyncStackFrame()
|
||||
{
|
||||
if (GetCurrentThreadId() != gUIThreadId) {
|
||||
if (!(mChannel->GetChannelFlags() & REQUIRE_DEFERRED_MESSAGE_PROTECTION)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -809,11 +811,9 @@ MessageChannel::WaitForSyncNotify()
|
|||
|
||||
MOZ_ASSERT(gUIThreadId, "InitUIThread was not called!");
|
||||
|
||||
// We jump through a lot of unique hoops in dealing with Windows message
|
||||
// trapping to prevent re-entrancy when we are blocked waiting on a sync
|
||||
// reply or new rpc in-call. However none of this overhead is needed when
|
||||
// we aren't on the main (gui) thread.
|
||||
if (GetCurrentThreadId() != gUIThreadId) {
|
||||
// Use a blocking wait if this channel does not require
|
||||
// Windows message deferral behavior.
|
||||
if (!(mFlags & REQUIRE_DEFERRED_MESSAGE_PROTECTION)) {
|
||||
PRIntervalTime timeout = (kNoTimeout == mTimeoutMs) ?
|
||||
PR_INTERVAL_NO_TIMEOUT :
|
||||
PR_MillisecondsToInterval(mTimeoutMs);
|
||||
|
@ -837,9 +837,8 @@ MessageChannel::WaitForSyncNotify()
|
|||
false : IsTimeoutExpired(waitStart, timeout));
|
||||
}
|
||||
|
||||
NS_ASSERTION(GetCurrentThreadId() == gUIThreadId,
|
||||
"Shouldn't be on a non-main thread in here!");
|
||||
|
||||
NS_ASSERTION(mFlags & REQUIRE_DEFERRED_MESSAGE_PROTECTION,
|
||||
"Shouldn't be here for channels that don't use message deferral!");
|
||||
NS_ASSERTION(mTopFrame && !mTopFrame->mInterrupt,
|
||||
"Top frame is not a sync frame!");
|
||||
|
||||
|
@ -961,21 +960,19 @@ MessageChannel::WaitForInterruptNotify()
|
|||
|
||||
MOZ_ASSERT(gUIThreadId, "InitUIThread was not called!");
|
||||
|
||||
// Re-use sync notification wait code when we aren't on the
|
||||
// gui thread, which bypasses the gui thread hoops we jump
|
||||
// through in dealing with Windows messaging.
|
||||
if (GetCurrentThreadId() != gUIThreadId) {
|
||||
// Re-use sync notification wait code if this channel does not require
|
||||
// Windows message deferral behavior.
|
||||
if (!(mFlags & REQUIRE_DEFERRED_MESSAGE_PROTECTION)) {
|
||||
return WaitForSyncNotify();
|
||||
}
|
||||
|
||||
NS_ASSERTION(GetCurrentThreadId() == gUIThreadId,
|
||||
"Shouldn't be on a non-main thread in here!");
|
||||
|
||||
if (!InterruptStackDepth()) {
|
||||
// There is currently no way to recover from this condition.
|
||||
NS_RUNTIMEABORT("StackDepth() is 0 in call to MessageChannel::WaitForNotify!");
|
||||
}
|
||||
|
||||
NS_ASSERTION(mFlags & REQUIRE_DEFERRED_MESSAGE_PROTECTION,
|
||||
"Shouldn't be here for channels that don't use message deferral!");
|
||||
NS_ASSERTION(mTopFrame && mTopFrame->mInterrupt,
|
||||
"Top frame is not a sync frame!");
|
||||
|
||||
|
|
|
@ -756,7 +756,7 @@ class B2GOptions(MochitestOptions):
|
|||
defaults["testPath"] = ""
|
||||
defaults["extensionsToExclude"] = ["specialpowers"]
|
||||
# See dependencies of bug 1038943.
|
||||
defaults["leakThreshold"] = 4964
|
||||
defaults["leakThreshold"] = 5012
|
||||
self.set_defaults(**defaults)
|
||||
|
||||
def verifyRemoteOptions(self, options):
|
||||
|
|
Загрузка…
Ссылка в новой задаче