static void DispatchSuspendResume(MediaDecoderReader* aSuspend,
                                    MediaDecoderReader* aResume)
  {
    RefPtr<MediaDecoderReader> suspend = aSuspend;
    RefPtr<MediaDecoderReader> resume = aResume;

    nsCOMPtr<nsIRunnable> task = NS_NewRunnableFunction(
      [suspend, resume] () {
        Suspend(suspend);
        DispatchResume(resume);
    });
    suspend->OwnerThread()->Dispatch(task.forget());
  }
  void Add(MediaDecoderReader* aReader)
  {
    MutexAutoLock lock(mMutex);

    if (mActive.Length() < mNumMaxActive) {
      // Below active limit, resume the new reader.
      mActive.AppendElement(aReader);
      DispatchResume(aReader);
    } else if (mActive.IsEmpty()) {
      MOZ_ASSERT(mNumMaxActive == 0);
      mSuspended.AppendElement(aReader);
    } else {
      // We're past the active limit, suspend an old reader and resume the new.
      mActive.AppendElement(aReader);
      MediaDecoderReader* suspendReader = mActive.ElementAt(0);
      mSuspended.AppendElement(suspendReader);
      mActive.RemoveElementAt(0);
      DispatchSuspendResume(suspendReader, aReader);
    }
  }
  void Remove(MediaDecoderReader* aReader)
  {
    MutexAutoLock lock(mMutex);

    // Remove the reader from the queue. Note that the reader's IsSuspended
    // state is updated on the task queue, so we cannot depend on it here to
    // determine the factual suspension state.
    DebugOnly<bool> suspended = mSuspended.RemoveElement(aReader);
    bool active = mActive.RemoveElement(aReader);

    MOZ_ASSERT(suspended || active, "Reader must be in the queue");

    if (active && !mSuspended.IsEmpty()) {
      // For each removed active reader, we resume a suspended one.
      MediaDecoderReader* resumeReader = mSuspended.LastElement();
      mActive.AppendElement(resumeReader);
      mSuspended.RemoveElementAt(mSuspended.Length() - 1);
      DispatchResume(resumeReader);
    }
  }
Example #4
0
  void Remove(MediaDecoderReader* aReader)
  {
    MutexAutoLock lock(mMutex);

    if (aReader->IsSuspended()) {
      // Removing suspended readers has no immediate side-effects.
      DebugOnly<bool> result = mSuspended.RemoveElement(aReader);
      MOZ_ASSERT(result, "Suspended reader must be in mSuspended");
    } else {
      // For each removed active reader, we resume a suspended one.
      DebugOnly<bool> result = mActive.RemoveElement(aReader);
      MOZ_ASSERT(result, "Non-suspended reader must be in mActive");
      if (mSuspended.IsEmpty()) {
        return;
      }
      MediaDecoderReader* resumeReader = mSuspended.LastElement();
      mActive.AppendElement(resumeReader);
      mSuspended.RemoveElementAt(mSuspended.Length() - 1);
      DispatchResume(resumeReader);
    }
  }