Backed out changeset 5a476e673470 (bug 1073615) for causing various intermittent failures.

This commit is contained in:
Ryan VanderMeulen 2014-11-12 11:52:30 -05:00
parent 5a82bddd3a
commit 1b0c318bb9
6 changed files with 33 additions and 50 deletions

View File

@ -65,7 +65,7 @@ PRLogModuleInfo* gMediaStreamGraphLog;
/**
* The singleton graph instance.
*/
static nsDataHashtable<nsUint32HashKey, MediaStreamGraphImpl*> gGraphs;
static MediaStreamGraphImpl* gGraph;
MediaStreamGraphImpl::~MediaStreamGraphImpl()
{
@ -1636,10 +1636,9 @@ MediaStreamGraphImpl::RunInStableState(bool aSourceIsMSG)
NS_DispatchToMainThread(event);
LIFECYCLE_LOG("Disconnecting MediaStreamGraph %p", this);
MediaStreamGraphImpl* graph;
if (gGraphs.Get(mAudioChannel, &graph) && graph == this) {
if (this == gGraph) {
// null out gGraph if that's the graph being shut down
gGraphs.Remove(mAudioChannel);
gGraph = nullptr;
}
}
} else {
@ -1790,12 +1789,9 @@ MediaStreamGraphImpl::AppendMessage(ControlMessage* aMessage)
delete aMessage;
if (IsEmpty() &&
mLifecycleState >= LIFECYCLE_WAITING_FOR_STREAM_DESTRUCTION) {
MediaStreamGraphImpl* graph;
if (gGraphs.Get(mAudioChannel, &graph) && graph == this) {
gGraphs.Remove(mAudioChannel);
if (gGraph == this) {
gGraph = nullptr;
}
Destroy();
}
return;
@ -2745,7 +2741,6 @@ MediaStreamGraphImpl::MediaStreamGraphImpl(bool aRealtime,
#ifdef DEBUG
, mCanRunMessagesSynchronously(false)
#endif
, mAudioChannel(static_cast<uint32_t>(aChannel))
{
#ifdef PR_LOGGING
if (!gMediaStreamGraphLog) {
@ -2784,26 +2779,15 @@ NS_IMPL_ISUPPORTS(MediaStreamGraphShutdownObserver, nsIObserver)
static bool gShutdownObserverRegistered = false;
namespace {
PLDHashOperator
ForceShutdownEnumerator(const uint32_t& /* aAudioChannel */,
MediaStreamGraphImpl* aGraph,
void* /* aUnused */)
{
aGraph->ForceShutDown();
return PL_DHASH_NEXT;
}
} // anonymous namespace
NS_IMETHODIMP
MediaStreamGraphShutdownObserver::Observe(nsISupports *aSubject,
const char *aTopic,
const char16_t *aData)
{
if (strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) {
gGraphs.EnumerateRead(ForceShutdownEnumerator, nullptr);
if (gGraph) {
gGraph->ForceShutDown();
}
nsContentUtils::UnregisterShutdownObserver(this);
gShutdownObserverRegistered = false;
}
@ -2815,10 +2799,7 @@ MediaStreamGraph::GetInstance(DOMMediaStream::TrackTypeHints aHint, dom::AudioCh
{
NS_ASSERTION(NS_IsMainThread(), "Main thread only");
uint32_t channel = static_cast<uint32_t>(aChannel);
MediaStreamGraphImpl* graph = nullptr;
if (!gGraphs.Get(channel, &graph)) {
if (!gGraph) {
if (!gShutdownObserverRegistered) {
gShutdownObserverRegistered = true;
nsContentUtils::RegisterShutdownObserver(new MediaStreamGraphShutdownObserver());
@ -2826,13 +2807,12 @@ MediaStreamGraph::GetInstance(DOMMediaStream::TrackTypeHints aHint, dom::AudioCh
CubebUtils::InitPreferredSampleRate();
graph = new MediaStreamGraphImpl(true, CubebUtils::PreferredSampleRate(), aHint, aChannel);
gGraphs.Put(channel, graph);
gGraph = new MediaStreamGraphImpl(true, CubebUtils::PreferredSampleRate(), aHint, aChannel);
STREAM_LOG(PR_LOG_DEBUG, ("Starting up MediaStreamGraph %p", graph));
STREAM_LOG(PR_LOG_DEBUG, ("Starting up MediaStreamGraph %p", gGraph));
}
return graph;
return gGraph;
}
MediaStreamGraph*
@ -3015,10 +2995,7 @@ MediaStreamGraph::CreateAudioNodeStream(AudioNodeEngine* aEngine,
bool
MediaStreamGraph::IsNonRealtime() const
{
const MediaStreamGraphImpl* impl = static_cast<const MediaStreamGraphImpl*>(this);
MediaStreamGraphImpl* graph;
return !gGraphs.Get(impl->AudioChannel(), &graph) || graph != impl;
return this != gGraph;
}
void

View File

@ -661,8 +661,6 @@ public:
nsRefPtr<AudioOutputObserver> mFarendObserverRef;
#endif
uint32_t AudioChannel() const { return mAudioChannel; }
private:
virtual ~MediaStreamGraphImpl();
@ -696,9 +694,6 @@ private:
bool mCanRunMessagesSynchronously;
#endif
// We use uint32_t instead AudioChannel because this is just used as key for
// the hashtable gGraphs.
uint32_t mAudioChannel;
};
}

View File

@ -654,6 +654,12 @@ AudioContext::MozAudioChannelType() const
return mDestination->MozAudioChannelType();
}
void
AudioContext::SetMozAudioChannelType(AudioChannel aValue, ErrorResult& aRv)
{
mDestination->SetMozAudioChannelType(aValue, aRv);
}
AudioChannel
AudioContext::TestAudioChannelInAudioNodeStream()
{

View File

@ -222,6 +222,7 @@ public:
JSObject* GetGlobalJSObject() const;
AudioChannel MozAudioChannelType() const;
void SetMozAudioChannelType(AudioChannel aValue, ErrorResult& aRv);
AudioChannel TestAudioChannelInAudioNodeStream();

View File

@ -18,23 +18,27 @@ function test_basic() {
// Default
is(ac.mozAudioChannelType, "normal", "Default ac channel == 'normal'");
// random wrong channel
ac.mozAudioChannelType = "foo";
is(ac.mozAudioChannelType, "normal", "Default ac channel == 'normal'");
// Unpermitted channels
ac = new AudioContext("content");
ac.mozAudioChannelType = "content";
is(ac.mozAudioChannelType, "normal", "Default ac channel == 'normal'");
ac = new AudioContext("notification");
ac.mozAudioChannelType = "notification";
is(ac.mozAudioChannelType, "normal", "Default ac channel == 'normal'");
ac = new AudioContext("alarm");
ac.mozAudioChannelType = "alarm";
is(ac.mozAudioChannelType, "normal", "Default ac channel == 'normal'");
ac = new AudioContext("telephony");
ac.mozAudioChannelType = "telephony";
is(ac.mozAudioChannelType, "normal", "Default ac channel == 'normal'");
ac = new AudioContext("ringer");
ac.mozAudioChannelType = "ringer";
is(ac.mozAudioChannelType, "normal", "Default ac channel == 'normal'");
ac = new AudioContext("publicnotification");
ac.mozAudioChannelType = "publicnotification";
is(ac.mozAudioChannelType, "normal", "Default ac channel == 'normal'");
runTest();
@ -52,7 +56,7 @@ function test_permission(aChannel) {
SpecialPowers.pushPermissions(
[{ "type": "audio-channel-" + aChannel, "allow": true, "context": document }],
function() {
var ac = new AudioContext(aChannel);
ac.mozAudioChannelType = aChannel;
is(ac.mozAudioChannelType, aChannel, "Default ac channel == '" + aChannel + "'");
var channel = SpecialPowers.wrap(ac).testAudioChannelInAudioNodeStream();

View File

@ -78,8 +78,8 @@ interface AudioContext : EventTarget {
// Mozilla extensions
partial interface AudioContext {
// Read AudioChannel.webidl for more information about this attribute.
[Pref="media.useAudioChannelService"]
readonly attribute AudioChannel mozAudioChannelType;
[Pref="media.useAudioChannelService", SetterThrows]
attribute AudioChannel mozAudioChannelType;
// These 2 events are dispatched when the AudioContext object is muted by
// the AudioChannelService. It's call 'interrupt' because when this event is