Bug 612799 (1/2) - Error reporting in Drain(). r=kinetik
authorPaul ADENOT <paul@paul.cx>
Fri, 10 Jun 2011 18:26:52 +0200
changeset 70877 9dbd24f893ff
parent 70876 243b53ce2461
child 70878 e109c624ae00
push id20435
push usereakhgari@mozilla.com
push dateFri, 10 Jun 2011 20:08:22 +0000
treeherdermozilla-central@28217403cd02 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskinetik
bugs612799
milestone7.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 612799 (1/2) - Error reporting in Drain(). r=kinetik
content/media/nsAudioStream.cpp
content/media/nsAudioStream.h
dom/ipc/AudioChild.cpp
dom/ipc/AudioChild.h
dom/ipc/AudioParent.cpp
dom/ipc/AudioParent.h
dom/ipc/PAudio.ipdl
--- a/content/media/nsAudioStream.cpp
+++ b/content/media/nsAudioStream.cpp
@@ -88,17 +88,17 @@ class nsAudioStreamLocal : public nsAudi
   ~nsAudioStreamLocal();
   nsAudioStreamLocal();
 
   nsresult Init(PRInt32 aNumChannels, PRInt32 aRate, SampleFormat aFormat);
   void Shutdown();
   nsresult Write(const void* aBuf, PRUint32 aCount, PRBool aBlocking);
   PRUint32 Available();
   void SetVolume(double aVolume);
-  void Drain();
+  nsresult Drain();
   void Pause();
   void Resume();
   PRInt64 GetPosition();
   PRInt64 GetSampleOffset();
   PRBool IsPaused();
   PRInt32 GetMinWriteSamples();
 
  private:
@@ -132,17 +132,17 @@ class nsAudioStreamRemote : public nsAud
   nsAudioStreamRemote();
   ~nsAudioStreamRemote();
 
   nsresult Init(PRInt32 aNumChannels, PRInt32 aRate, SampleFormat aFormat);
   void Shutdown();
   nsresult Write(const void* aBuf, PRUint32 aCount, PRBool aBlocking);
   PRUint32 Available();
   void SetVolume(double aVolume);
-  void Drain();
+  nsresult Drain();
   void Pause();
   void Resume();
   PRInt64 GetPosition();
   PRInt64 GetSampleOffset();
   PRBool IsPaused();
   PRInt32 GetMinWriteSamples();
 
 private:
@@ -555,38 +555,40 @@ void nsAudioStreamLocal::SetVolume(doubl
     PR_LOG(gAudioStreamLog, PR_LOG_ERROR, ("nsAudioStreamLocal: sa_stream_set_volume_abs error"));
     mInError = PR_TRUE;
   }
 #else
   mVolume = aVolume;
 #endif
 }
 
-void nsAudioStreamLocal::Drain()
+nsresult nsAudioStreamLocal::Drain()
 {
   NS_ASSERTION(!mPaused, "Don't drain audio when paused, it won't finish!");
 
   if (mInError)
-    return;
+    return NS_ERROR_FAILURE;
 
   // Write any remaining unwritten sound data in the overflow buffer
   if (!mBufferOverflow.IsEmpty()) {
     if (sa_stream_write(static_cast<sa_stream_t*>(mAudioHandle),
                         mBufferOverflow.Elements(),
                         mBufferOverflow.Length() * sizeof(short)) != SA_SUCCESS)
       PR_LOG(gAudioStreamLog, PR_LOG_ERROR, ("nsAudioStreamLocal: sa_stream_write error"));
       mInError = PR_TRUE;
-      return;
+      return NS_ERROR_FAILURE;
   }
 
   int r = sa_stream_drain(static_cast<sa_stream_t*>(mAudioHandle));
   if (r != SA_SUCCESS && r != SA_ERROR_INVALID) {
     PR_LOG(gAudioStreamLog, PR_LOG_ERROR, ("nsAudioStreamLocal: sa_stream_drain error"));
     mInError = PR_TRUE;
+    return NS_ERROR_FAILURE;
   }
+  return NS_OK;
 }
 
 void nsAudioStreamLocal::Pause()
 {
   if (mInError)
     return;
   mPaused = PR_TRUE;
   sa_stream_pause(static_cast<sa_stream_t*>(mAudioHandle));
@@ -734,26 +736,26 @@ void
 nsAudioStreamRemote::SetVolume(double aVolume)
 {
   if (!mAudioChild)
     return;
   nsCOMPtr<nsIRunnable> event = new AudioSetVolumeEvent(mAudioChild, aVolume);
   NS_DispatchToMainThread(event);
 }
 
-void
+nsresult
 nsAudioStreamRemote::Drain()
 {
   if (!mAudioChild)
-    return;
+    return NS_ERROR_FAILURE;
   nsCOMPtr<nsIRunnable> event = new AudioDrainEvent(mAudioChild);
   NS_DispatchToMainThread(event);
-  mAudioChild->WaitForDrain();
+  return mAudioChild->WaitForDrain();
 }
- 
+
 void
 nsAudioStreamRemote::Pause()
 {
   mPaused = PR_TRUE;
   if (!mAudioChild)
     return;
   nsCOMPtr<nsIRunnable> event = new AudioPauseEvent(mAudioChild, PR_TRUE);
   NS_DispatchToMainThread(event);
--- a/content/media/nsAudioStream.h
+++ b/content/media/nsAudioStream.h
@@ -93,17 +93,17 @@ public:
   // without blocking.
   virtual PRUint32 Available() = 0;
 
   // Set the current volume of the audio playback. This is a value from
   // 0 (meaning muted) to 1 (meaning full volume).
   virtual void SetVolume(double aVolume) = 0;
 
   // Block until buffered audio data has been consumed.
-  virtual void Drain() = 0;
+  virtual nsresult Drain() = 0;
 
   // Pause audio playback
   virtual void Pause() = 0;
 
   // Resume audio playback
   virtual void Resume() = 0;
 
   // Return the position in microseconds of the sample being played by the
--- a/dom/ipc/AudioChild.cpp
+++ b/dom/ipc/AudioChild.cpp
@@ -71,20 +71,23 @@ AudioChild::RecvSampleOffsetUpdate(const
                                    const PRInt64& time)
 {
   mLastSampleOffset = offset;
   mLastSampleOffsetTime = time;
   return true;
 }
 
 bool
-AudioChild::RecvDrainDone()
+AudioChild::RecvDrainDone(const nsresult& status)
 {
   ReentrantMonitorAutoEnter mon(mAudioReentrantMonitor);
-  mDrained = PR_TRUE;
+
+  if (status == NS_OK)
+    mDrained = PR_TRUE;
+
   mAudioReentrantMonitor.NotifyAll();
   return true;
 }
 
 PRInt32
 AudioChild::WaitForMinWriteSample()
 {
   ReentrantMonitorAutoEnter mon(mAudioReentrantMonitor);
@@ -98,23 +101,27 @@ bool
 AudioChild::RecvMinWriteSampleDone(const PRInt32& minSamples)
 {
   ReentrantMonitorAutoEnter mon(mAudioReentrantMonitor);
   mMinWriteSample = minSamples;
   mAudioReentrantMonitor.NotifyAll();
   return true;
 }
 
-void
+nsresult
 AudioChild::WaitForDrain()
 {
   ReentrantMonitorAutoEnter mon(mAudioReentrantMonitor);
   while (!mDrained && mIPCOpen) {
     mAudioReentrantMonitor.Wait();
   }
+  if (mDrained)
+    return NS_OK;
+
+  return NS_ERROR_FAILURE;
 }
 
 PRInt64
 AudioChild::GetLastKnownSampleOffset()
 {
   return mLastSampleOffset;
 }
 
--- a/dom/ipc/AudioChild.h
+++ b/dom/ipc/AudioChild.h
@@ -50,20 +50,20 @@ class AudioChild : public PAudioChild
 {
  public:
     NS_IMETHOD_(nsrefcnt) AddRef();
     NS_IMETHOD_(nsrefcnt) Release();
 
     AudioChild();
     virtual ~AudioChild();
     virtual bool RecvSampleOffsetUpdate(const PRInt64&, const PRInt64&);
-    virtual bool RecvDrainDone();
+    virtual bool RecvDrainDone(const nsresult& status);
     virtual PRInt32 WaitForMinWriteSample();
     virtual bool RecvMinWriteSampleDone(const PRInt32& sampleCount);
-    virtual void WaitForDrain();
+    virtual nsresult WaitForDrain();
     virtual void ActorDestroy(ActorDestroyReason);
 
     PRInt64 GetLastKnownSampleOffset();
     PRInt64 GetLastKnownSampleOffsetTime();
 
     PRBool IsIPCOpen() { return mIPCOpen; };
  private:
     nsAutoRefCnt mRefCnt;
--- a/dom/ipc/AudioParent.cpp
+++ b/dom/ipc/AudioParent.cpp
@@ -149,44 +149,46 @@ class AudioMinWriteSampleEvent : public 
  private:
     nsRefPtr<nsAudioStream> mOwner;
     nsRefPtr<AudioParent> mParent;
 };
 
 class AudioDrainDoneEvent : public nsRunnable
 {
  public:
-  AudioDrainDoneEvent(AudioParent* owner)
+  AudioDrainDoneEvent(AudioParent* owner, nsresult status)
   {
     mOwner = owner;
+    mStatus = status;
   }
 
   NS_IMETHOD Run()
   {
-    mOwner->SendDrainDone();
+    mOwner->SendDrainDone(mStatus);
     return NS_OK;
   }
 
  private:
     nsRefPtr<AudioParent> mOwner;
+    nsresult mStatus;
 };
 
 class AudioDrainEvent : public nsRunnable
 {
  public:
   AudioDrainEvent(AudioParent* parent, nsAudioStream* owner)
   {
     mParent = parent;
     mOwner = owner;
   }
 
   NS_IMETHOD Run()
   {
-    mOwner->Drain();
-    nsCOMPtr<nsIRunnable> event = new AudioDrainDoneEvent(mParent);
+    nsresult rv = mOwner->Drain();
+    nsCOMPtr<nsIRunnable> event = new AudioDrainDoneEvent(mParent, rv);
     NS_DispatchToMainThread(event);
     return NS_OK;
   }
 
  private:
     nsRefPtr<nsAudioStream> mOwner;
     nsRefPtr<AudioParent> mParent;
 };
@@ -285,20 +287,20 @@ bool
 AudioParent::SendMinWriteSampleDone(PRInt32 minSamples)
 {
   if (mIPCOpen)
     return PAudioParent::SendMinWriteSampleDone(minSamples);
   return true;
 }
 
 bool
-AudioParent::SendDrainDone()
+AudioParent::SendDrainDone(nsresult status)
 {
   if (mIPCOpen)
-    return PAudioParent::SendDrainDone();
+    return PAudioParent::SendDrainDone(status);
   return true;
 }
 
 AudioParent::AudioParent(PRInt32 aNumChannels, PRInt32 aRate, PRInt32 aFormat)
   : mIPCOpen(PR_TRUE)
 {
   mStream = nsAudioStream::AllocateStream();
   NS_ASSERTION(mStream, "AudioStream allocation failed.");
--- a/dom/ipc/AudioParent.h
+++ b/dom/ipc/AudioParent.h
@@ -75,17 +75,17 @@ class AudioParent : public PAudioParent,
 
     virtual bool
     RecvShutdown();
 
     virtual bool
     SendMinWriteSampleDone(PRInt32 minSamples);
 
     virtual bool
-    SendDrainDone();
+    SendDrainDone(nsresult status);
 
     AudioParent(PRInt32 aNumChannels, PRInt32 aRate, PRInt32 aFormat);
     virtual ~AudioParent();
     virtual void ActorDestroy(ActorDestroyReason);
 
     nsRefPtr<nsAudioStream> mStream;
     nsCOMPtr<nsITimer> mTimer;
 
--- a/dom/ipc/PAudio.ipdl
+++ b/dom/ipc/PAudio.ipdl
@@ -60,14 +60,14 @@ parent:
   Shutdown();
 
  child:
 
   __delete__();
 
   SampleOffsetUpdate(PRInt64 offset, PRInt64 time);
   MinWriteSampleDone(PRInt32 sampleCount);
-  DrainDone();
+  DrainDone(nsresult status);
 
 };
 
 } // namespace dom
 } // namespace mozilla