Example #1
0
void
WorkerFetchResolver::OnResponseEnd()
{
  AssertIsOnMainThread();
  MutexAutoLock lock(mPromiseProxy->Lock());
  if (mPromiseProxy->CleanedUp()) {
    return;
  }

  FlushConsoleReport();

  RefPtr<WorkerFetchResponseEndRunnable> r =
    new WorkerFetchResponseEndRunnable(mPromiseProxy);

  if (!r->Dispatch()) {
    RefPtr<WorkerFetchResponseEndControlRunnable> cr =
      new WorkerFetchResponseEndControlRunnable(mPromiseProxy);
    // This can fail if the worker thread is canceled or killed causing
    // the PromiseWorkerProxy to give up its WorkerHolder immediately,
    // allowing the worker thread to become Dead.
    if (!cr->Dispatch()) {
      NS_WARNING("Failed to dispatch WorkerFetchResponseEndControlRunnable");
    }
  }
}
NS_IMETHODIMP
WorkerEventTarget::Dispatch(already_AddRefed<nsIRunnable> aRunnable,
                            uint32_t aFlags) {
  nsCOMPtr<nsIRunnable> runnable(aRunnable);

  MutexAutoLock lock(mMutex);

  if (!mWorkerPrivate) {
    return NS_ERROR_FAILURE;
  }

  if (mBehavior == Behavior::Hybrid) {
    RefPtr<WorkerRunnable> r =
        mWorkerPrivate->MaybeWrapAsWorkerRunnable(runnable.forget());
    if (r->Dispatch()) {
      return NS_OK;
    }

    runnable = r.forget();
  }

  RefPtr<WorkerControlRunnable> r =
      new WrappedControlRunnable(mWorkerPrivate, runnable.forget());
  if (!r->Dispatch()) {
    return NS_ERROR_FAILURE;
  }

  return NS_OK;
}
Example #3
0
void
BroadcastChannel::Shutdown()
{
  mState = StateClosed;

  // The DTOR of this WorkerRef will release the worker for us.
  mWorkerRef = nullptr;

  if (mActor) {
    mActor->SetParent(nullptr);

    if (NS_IsMainThread()) {
      RefPtr<TeardownRunnableOnMainThread> runnable =
        new TeardownRunnableOnMainThread(mActor);
      NS_DispatchToCurrentThread(runnable);
    } else {
      WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
      MOZ_ASSERT(workerPrivate);

      RefPtr<TeardownRunnableOnWorker> runnable =
        new TeardownRunnableOnWorker(workerPrivate, mActor);
      runnable->Dispatch();
    }

    mActor = nullptr;
  }

  IgnoreKeepAliveIfHasListenersFor(NS_LITERAL_STRING("message"));
}
Example #4
0
  NS_IMETHOD
  OnPushSubscription(nsresult aStatus,
                     nsIPushSubscription* aSubscription) override
  {
    AssertIsOnMainThread();
    MOZ_ASSERT(mProxy, "OnPushSubscription() called twice?");

    MutexAutoLock lock(mProxy->Lock());
    if (mProxy->CleanedUp()) {
      return NS_OK;
    }

    nsAutoString endpoint;
    nsTArray<uint8_t> rawP256dhKey, authSecret, appServerKey;
    if (NS_SUCCEEDED(aStatus)) {
      aStatus = GetSubscriptionParams(aSubscription, endpoint, rawP256dhKey,
                                      authSecret, appServerKey);
    }

    WorkerPrivate* worker = mProxy->GetWorkerPrivate();
    RefPtr<GetSubscriptionResultRunnable> r =
      new GetSubscriptionResultRunnable(worker,
                                        mProxy.forget(),
                                        aStatus,
                                        endpoint,
                                        mScope,
                                        Move(rawP256dhKey),
                                        Move(authSecret),
                                        Move(appServerKey));
    MOZ_ALWAYS_TRUE(r->Dispatch());

    return NS_OK;
  }
Example #5
0
already_AddRefed<Promise>
WorkerDataStore::Remove(JSContext* aCx,
                        const StringOrUnsignedLong& aId,
                        const nsAString& aRevisionId,
                        ErrorResult& aRv)
{
  WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(aCx);
  MOZ_ASSERT(workerPrivate);
  workerPrivate->AssertIsOnWorkerThread();

  RefPtr<Promise> promise = Promise::Create(workerPrivate->GlobalScope(), aRv);
  if (aRv.Failed()) {
    return nullptr;
  }

  RefPtr<DataStoreRemoveRunnable> runnable =
    new DataStoreRemoveRunnable(workerPrivate,
                                mBackingStore,
                                promise,
                                aId,
                                aRevisionId);
  runnable->Dispatch(aRv);
  if (aRv.Failed()) {
    return nullptr;
  }

  if (runnable->Failed()) {
    aRv.Throw(NS_ERROR_FAILURE);
    return nullptr;
  }

  return promise.forget();
}
void
CacheFileContextEvictor::StartEvicting()
{
  LOG(("CacheFileContextEvictor::StartEvicting() [this=%p]", this));

  MOZ_ASSERT(CacheFileIOManager::IsOnIOThread());

  if (mEvicting) {
    LOG(("CacheFileContextEvictor::StartEvicting() - already evicintg."));
    return;
  }

  if (mEntries.Length() == 0) {
    LOG(("CacheFileContextEvictor::StartEvicting() - no context to evict."));
    return;
  }

  nsCOMPtr<nsIRunnable> ev;
  ev = NS_NewRunnableMethod(this, &CacheFileContextEvictor::EvictEntries);

  RefPtr<CacheIOThread> ioThread = CacheFileIOManager::IOThread();

  nsresult rv = ioThread->Dispatch(ev, CacheIOThread::EVICT);
  if (NS_FAILED(rv)) {
    LOG(("CacheFileContextEvictor::StartEvicting() - Cannot dispatch event to "
         "IO thread. [rv=0x%08x]", rv));
  }

  mEvicting = true;
}
void
WebrtcGmpVideoEncoder::RegetEncoderForResolutionChange(
    uint32_t aWidth,
    uint32_t aHeight,
    const RefPtr<GmpInitDoneRunnable>& aInitDone)
{
  Close_g();

  UniquePtr<GetGMPVideoEncoderCallback> callback(
    new InitDoneForResolutionChangeCallback(this,
                                            aInitDone,
                                            aWidth,
                                            aHeight));

  // OpenH264 codec (at least) can't handle dynamic input resolution changes
  // re-init the plugin when the resolution changes
  // XXX allow codec to indicate it doesn't need re-init!
  nsTArray<nsCString> tags;
  tags.AppendElement(NS_LITERAL_CSTRING("h264"));
  mInitting = true;
  if (NS_WARN_IF(NS_FAILED(mMPS->GetGMPVideoEncoder(&tags,
                                                    NS_LITERAL_CSTRING(""),
                                                    Move(callback))))) {
    aInitDone->Dispatch(WEBRTC_VIDEO_CODEC_ERROR,
                        "GMP Encode: GetGMPVideoEncoder failed");
  }
}
Example #8
0
already_AddRefed<Promise>
WorkerDataStore::GetLength(JSContext* aCx, ErrorResult& aRv)
{
  WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(aCx);
  MOZ_ASSERT(workerPrivate);
  workerPrivate->AssertIsOnWorkerThread();

  RefPtr<Promise> promise = Promise::Create(workerPrivate->GlobalScope(), aRv);
  if (aRv.Failed()) {
    return nullptr;
  }

  RefPtr<DataStoreGetLengthRunnable> runnable =
    new DataStoreGetLengthRunnable(workerPrivate,
                                   mBackingStore,
                                   promise);
  runnable->Dispatch(aRv);
  if (aRv.Failed()) {
    return nullptr;
  }

  if (runnable->Failed()) {
    aRv.Throw(NS_ERROR_FAILURE);
    return nullptr;
  }

  return promise.forget();
}
Example #9
0
already_AddRefed<WorkerDataStoreCursor>
WorkerDataStore::Sync(JSContext* aCx,
                      const nsAString& aRevisionId,
                      ErrorResult& aRv)
{
  WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(aCx);
  MOZ_ASSERT(workerPrivate);
  workerPrivate->AssertIsOnWorkerThread();

  // Create a WorkerDataStoreCursor on the worker. Note that we need to pass
  // this WorkerDataStore into the WorkerDataStoreCursor, so that it can keep
  // track of which WorkerDataStore owns the WorkerDataStoreCursor.
  RefPtr<WorkerDataStoreCursor> workerCursor =
    new WorkerDataStoreCursor(this);

  // DataStoreSyncStoreRunnable will point the WorkerDataStoreCursor to the
  // DataStoreCursor created on the main thread.
  RefPtr<DataStoreSyncStoreRunnable> runnable =
    new DataStoreSyncStoreRunnable(workerPrivate,
                                   mBackingStore,
                                   workerCursor,
                                   aRevisionId);
  runnable->Dispatch(aRv);
  if (aRv.Failed()) {
    return nullptr;
  }

  if (runnable->Failed()) {
    aRv.Throw(NS_ERROR_FAILURE);
    return nullptr;
  }

  return workerCursor.forget();
}
Example #10
0
NS_IMETHODIMP
DataStoreChangeEventProxy::HandleEvent(nsIDOMEvent* aEvent)
{
  AssertIsOnMainThread();

  MutexAutoLock lock(mCleanUpLock);
  // If the worker thread's been cancelled we don't need to dispatch the event.
  if (mCleanedUp) {
    return NS_OK;
  }

  RefPtr<DataStoreChangeEvent> event =
    static_cast<DataStoreChangeEvent*>(aEvent);

  RefPtr<DispatchDataStoreChangeEventRunnable> runnable =
    new DispatchDataStoreChangeEventRunnable(this, event);

  {
    AutoSafeJSContext cx;
    JSAutoRequest ar(cx);
    runnable->Dispatch(cx);
  }

  return NS_OK;
}
Example #11
0
 NS_IMETHOD Run()
 {
     char aLocal;
     STREAM_LOG(LogLevel::Debug, ("Starting system thread"));
     profiler_register_thread("MediaStreamGraph", &aLocal);
     LIFECYCLE_LOG("Starting a new system driver for graph %p\n",
                   mDriver->mGraphImpl);
     if (mDriver->mPreviousDriver) {
         LIFECYCLE_LOG("%p releasing an AudioCallbackDriver(%p), for graph %p\n",
                       mDriver,
                       mDriver->mPreviousDriver.get(),
                       mDriver->GraphImpl());
         MOZ_ASSERT(!mDriver->AsAudioCallbackDriver());
         // Stop and release the previous driver off-main-thread, but only if we're
         // not in the situation where we've fallen back to a system clock driver
         // because the osx audio stack is currently switching output device.
         if (!mDriver->mPreviousDriver->AsAudioCallbackDriver()->IsSwitchingDevice()) {
             RefPtr<AsyncCubebTask> releaseEvent =
                 new AsyncCubebTask(mDriver->mPreviousDriver->AsAudioCallbackDriver(), AsyncCubebOperation::SHUTDOWN);
             mDriver->mPreviousDriver = nullptr;
             releaseEvent->Dispatch();
         }
     } else {
         MonitorAutoLock mon(mDriver->mGraphImpl->GetMonitor());
         MOZ_ASSERT(mDriver->mGraphImpl->MessagesQueued(), "Don't start a graph without messages queued.");
         mDriver->mGraphImpl->SwapMessageQueues();
     }
     mDriver->RunThread();
     return NS_OK;
 }
Example #12
0
void
AudioCallbackDriver::Start()
{
    // If this is running on the main thread, we can't open the stream directly,
    // because it is a blocking operation.
    if (NS_IsMainThread()) {
        STREAM_LOG(LogLevel::Debug, ("Starting audio threads for MediaStreamGraph %p from a new thread.", mGraphImpl));
        RefPtr<AsyncCubebTask> initEvent =
            new AsyncCubebTask(this, AsyncCubebOperation::INIT);
        initEvent->Dispatch();
    } else {
        STREAM_LOG(LogLevel::Debug, ("Starting audio threads for MediaStreamGraph %p from the previous driver's thread", mGraphImpl));
        Init();

        // Check if we need to resolve promises because the driver just got switched
        // because of a resuming AudioContext
        if (!mPromisesForOperation.IsEmpty()) {
            CompleteAudioContextOperations(AsyncCubebOperation::INIT);
        }

        if (mPreviousDriver) {
            nsCOMPtr<nsIRunnable> event =
                new MediaStreamGraphShutdownThreadRunnable(mPreviousDriver);
            mPreviousDriver = nullptr;
            NS_DispatchToMainThread(event);
        }
    }
}
Example #13
0
void
TimeoutManager::CancelOrUpdateBackPressure(nsGlobalWindow* aWindow)
{
  MOZ_ASSERT(NS_IsMainThread());
  MOZ_ASSERT(aWindow == &mWindow);
  MOZ_ASSERT(mBackPressureDelayMS > 0);

  // First, re-calculate the back pressure delay.
  RefPtr<ThrottledEventQueue> queue =
    do_QueryObject(mWindow.TabGroup()->EventTargetFor(TaskCategory::Timer));
  int32_t newBackPressureDelayMS =
    CalculateNewBackPressureDelayMS(queue ? queue->Length() : 0);

  // If the delay has increased, then simply apply it.  Increasing the delay
  // does not risk re-ordering timers with similar parameters.  We want to
  // extra careful not to re-order sequential calls to setTimeout(func, 0),
  // for example.
  if (newBackPressureDelayMS > mBackPressureDelayMS) {
    mBackPressureDelayMS = newBackPressureDelayMS;
  }

  // If the delay has decreased, though, we only apply the new value if it has
  // reduced significantly.  This hysteresis avoids thrashing the back pressure
  // value back and forth rapidly.  This is important because reducing the
  // backpressure delay requires calling ResetTimerForThrottleReduction() which
  // can be quite expensive.  We only want to call that method if the back log
  // is really clearing.
  else if (newBackPressureDelayMS == 0 ||
           (newBackPressureDelayMS <=
           (mBackPressureDelayMS - kBackPressureDelayReductionThresholdMS))) {
    int32_t oldBackPressureDelayMS = mBackPressureDelayMS;
    mBackPressureDelayMS = newBackPressureDelayMS;

    // If the back pressure delay has gone down we must reset any existing
    // timers to use the new value.  Otherwise we run the risk of executing
    // timer callbacks out-of-order.
    ResetTimersForThrottleReduction(oldBackPressureDelayMS);
  }

  // If all of the back pressure delay has been removed then we no longer need
  // to check back pressure updates.  We can simply return without scheduling
  // another update runnable.
  if (!mBackPressureDelayMS) {
    return;
  }

  // Otherwise, if there is a back pressure delay still in effect we need
  // queue a runnable to check if it can be reduced in the future.  Note
  // that this runnable is dispatched to the ThrottledEventQueue.  This
  // means we will not check for a new value until the current back log
  // has been processed.  The next update will only keep back pressure if
  // more runnables continue to be dispatched to the queue.
  nsCOMPtr<nsIRunnable> r =
    NewNonOwningRunnableMethod<StoreRefPtrPassByPtr<nsGlobalWindow>>(this,
      &TimeoutManager::CancelOrUpdateBackPressure, &mWindow);
  MOZ_ALWAYS_SUCCEEDS(queue->Dispatch(r.forget(), NS_DISPATCH_NORMAL));
}
NS_IMETHODIMP
WifiCertService::ImportCert(int32_t aId, nsIDOMBlob* aCertBlob,
                            const nsAString& aCertPassword,
                            const nsAString& aCertNickname)
{
  nsRefPtr<Blob> blob = static_cast<Blob*>(aCertBlob);
  RefPtr<CryptoTask> task = new ImportCertTask(aId, blob, aCertPassword,
                                               aCertNickname);
  return task->Dispatch("WifiImportCert");
}
Example #15
0
void
WorkerNavigator::GetUserAgent(nsString& aUserAgent, ErrorResult& aRv) const
{
  WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
  MOZ_ASSERT(workerPrivate);

  RefPtr<GetUserAgentRunnable> runnable =
    new GetUserAgentRunnable(workerPrivate, aUserAgent);

  runnable->Dispatch(aRv);
}
Example #16
0
void GraphDriver::Shutdown()
{
    if (AsAudioCallbackDriver()) {
        LIFECYCLE_LOG("Releasing audio driver off main thread (GraphDriver::Shutdown).\n");
        RefPtr<AsyncCubebTask> releaseEvent =
            new AsyncCubebTask(AsAudioCallbackDriver(), AsyncCubebOperation::SHUTDOWN);
        releaseEvent->Dispatch();
    } else {
        Stop();
    }
}
Example #17
0
void Worker::PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
                         const Sequence<JSObject*>& aTransferable,
                         ErrorResult& aRv) {
  NS_ASSERT_OWNINGTHREAD(Worker);

  if (!mWorkerPrivate || mWorkerPrivate->ParentStatusProtected() > Running) {
    return;
  }

  JS::Rooted<JS::Value> transferable(aCx, JS::UndefinedValue());

  aRv = nsContentUtils::CreateJSValueFromSequenceOfObject(aCx, aTransferable,
                                                          &transferable);
  if (NS_WARN_IF(aRv.Failed())) {
    return;
  }

  RefPtr<MessageEventRunnable> runnable = new MessageEventRunnable(
      mWorkerPrivate, WorkerRunnable::WorkerThreadModifyBusyCount);

  UniquePtr<AbstractTimelineMarker> start;
  UniquePtr<AbstractTimelineMarker> end;
  RefPtr<TimelineConsumers> timelines = TimelineConsumers::Get();
  bool isTimelineRecording = timelines && !timelines->IsEmpty();

  if (isTimelineRecording) {
    start = MakeUnique<WorkerTimelineMarker>(
        NS_IsMainThread()
            ? ProfileTimelineWorkerOperationType::SerializeDataOnMainThread
            : ProfileTimelineWorkerOperationType::SerializeDataOffMainThread,
        MarkerTracingType::START);
  }

  runnable->Write(aCx, aMessage, transferable, JS::CloneDataPolicy(), aRv);

  if (isTimelineRecording) {
    end = MakeUnique<WorkerTimelineMarker>(
        NS_IsMainThread()
            ? ProfileTimelineWorkerOperationType::SerializeDataOnMainThread
            : ProfileTimelineWorkerOperationType::SerializeDataOffMainThread,
        MarkerTracingType::END);
    timelines->AddMarkerForAllObservedDocShells(start);
    timelines->AddMarkerForAllObservedDocShells(end);
  }

  if (NS_WARN_IF(aRv.Failed())) {
    return;
  }

  if (!runnable->Dispatch()) {
    aRv.Throw(NS_ERROR_FAILURE);
  }
}
Example #18
0
/* static */ void
UiCompositorControllerChild::InitSameProcess(RefPtr<nsThread> aThread)
{
  MOZ_ASSERT(!sChild);
  MOZ_ASSERT(!sParent);
  MOZ_ASSERT(aThread);
  MOZ_ASSERT(!sInitialized);

  sInitialized = true;
  RefPtr<UiCompositorControllerChild> child = new UiCompositorControllerChild(aThread, 0);
  sParent = new UiCompositorControllerParent();
  aThread->Dispatch(NewRunnableMethod(child, &UiCompositorControllerChild::OpenForSameProcess), nsIThread::DISPATCH_NORMAL);
}
Example #19
0
void
WorkerDataStore::GetOwner(JSContext* aCx, nsAString& aOwner, ErrorResult& aRv)
{
  WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(aCx);
  MOZ_ASSERT(workerPrivate);
  workerPrivate->AssertIsOnWorkerThread();

  RefPtr<DataStoreGetStringRunnable> runnable =
    new DataStoreGetStringRunnable(workerPrivate,
                                   mBackingStore,
                                   &DataStore::GetOwner,
                                   aOwner);
  runnable->Dispatch(aRv);
}
Example #20
0
 ~AutoFailConsumeBody()
 {
   AssertIsOnMainThread();
   if (mBody) {
     if (mBody->mWorkerPrivate) {
       RefPtr<FailConsumeBodyWorkerRunnable<Derived>> r =
         new FailConsumeBodyWorkerRunnable<Derived>(mBody);
       if (!r->Dispatch()) {
         MOZ_CRASH("We are going to leak");
       }
     } else {
       mBody->ContinueConsumeBody(NS_ERROR_FAILURE, 0, nullptr);
     }
   }
 }
Example #21
0
void
FetchStream::ReleaseObjects(const MutexAutoLock& aProofOfLock)
{
  // This method can be called on 2 possible threads: the owning one and a JS
  // thread used to release resources. If we are on the JS thread, we need to
  // dispatch a runnable to go back to the owning thread in order to release
  // resources correctly.

  if (mState == eClosed) {
    // Already gone. Nothing to do.
    return;
  }

  mState = eClosed;

  if (!NS_IsMainThread() && !IsCurrentThreadRunningWorker()) {
    // Let's dispatch a WorkerControlRunnable if the owning thread is a worker.
    if (mWorkerRef) {
      RefPtr<WorkerShutdown> r =
        new WorkerShutdown(mWorkerRef->GetUnsafePrivate(), this);
      Unused << NS_WARN_IF(!r->Dispatch());
      return;
    }

    // A normal runnable of the owning thread is the main-thread.
    RefPtr<FetchStream> self = this;
    RefPtr<Runnable> r =
      NS_NewRunnableFunction("FetchStream::ReleaseObjects",
                             [self] () { self->ReleaseObjects(); });
    mOwningEventTarget->Dispatch(r.forget());
    return;
  }

  AssertIsOnOwningThread();

  if (NS_IsMainThread()) {
    nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
    if (obs) {
      obs->RemoveObserver(this, DOM_WINDOW_DESTROYED_TOPIC);
    }
  }

  mWorkerRef = nullptr;
  mGlobal = nullptr;

  mStreamHolder->NullifyStream();
  mStreamHolder = nullptr;
}
Example #22
0
 virtual ~TestBinding()
 {
   {
     RefPtr<TaskQueue> queue = reader->OwnerThread();
     nsCOMPtr<nsIRunnable> task = NS_NewRunnableMethod(reader, &MP4Reader::Shutdown);
     // Hackily bypass the tail dispatcher so that we can AwaitShutdownAndIdle.
     // In production code we'd use BeginShutdown + promises.
     queue->Dispatch(task.forget(), AbstractThread::AssertDispatchSuccess,
                     AbstractThread::TailDispatch);
     queue->AwaitShutdownAndIdle();
   }
   decoder = nullptr;
   resource = nullptr;
   reader = nullptr;
   SharedThreadPool::SpinUntilEmpty();
 }
Example #23
0
bool
WorkerDataStore::GetReadOnly(JSContext* aCx, ErrorResult& aRv)
{
  WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(aCx);
  MOZ_ASSERT(workerPrivate);
  workerPrivate->AssertIsOnWorkerThread();

  RefPtr<DataStoreGetReadOnlyRunnable> runnable =
    new DataStoreGetReadOnlyRunnable(workerPrivate, mBackingStore);
  runnable->Dispatch(aRv);
  if (aRv.Failed()) {
    return true; // To be safe, I guess.
  }

  return runnable->mReadOnly;
}
Example #24
0
void
WorkerFetchResolver::OnResponseEnd()
{
  AssertIsOnMainThread();
  MutexAutoLock lock(mPromiseProxy->Lock());
  if (mPromiseProxy->CleanedUp()) {
    return;
  }

  RefPtr<WorkerFetchResponseEndRunnable> r =
    new WorkerFetchResponseEndRunnable(mPromiseProxy->GetWorkerPrivate(), this);

  if (!r->Dispatch()) {
    NS_WARNING("Could not dispatch fetch response end");
  }
}
Example #25
0
void
AudioStream::Reset()
{

  MOZ_ASSERT(mLatencyRequest == LowLatency, "We should only be reseting low latency streams");

  mShouldDropFrames = true;
  mNeedsStart = true;

  cubeb_stream_params params;
  params.rate = mInRate;
  params.channels = mOutChannels;
#if defined(__ANDROID__)
#if defined(MOZ_B2G)
  params.stream_type = CubebUtils::ConvertChannelToCubebType(mAudioChannel);
#else
  params.stream_type = CUBEB_STREAM_TYPE_MUSIC;
#endif

  if (params.stream_type == CUBEB_STREAM_TYPE_MAX) {
    return;
  }
#endif

  if (AUDIO_OUTPUT_FORMAT == AUDIO_FORMAT_S16) {
    params.format = CUBEB_SAMPLE_S16NE;
  } else {
    params.format = CUBEB_SAMPLE_FLOAT32NE;
  }
  mBytesPerFrame = sizeof(AudioDataValue) * mOutChannels;

  // Size mBuffer for one second of audio.  This value is arbitrary, and was
  // selected based on the observed behaviour of the existing AudioStream
  // implementations.
  uint32_t bufferLimit = FramesToBytes(mInRate);
  MOZ_ASSERT(bufferLimit % mBytesPerFrame == 0, "Must buffer complete frames");
  mBuffer.Reset();
  mBuffer.SetCapacity(bufferLimit);

  // Don't block this thread to initialize a cubeb stream.
  // When this is done, it will start callbacks from Cubeb.  Those will
  // cause us to move from INITIALIZED to RUNNING.  Until then, we
  // can't access any cubeb functions.
  // Use a RefPtr to avoid leaks if Dispatch fails
  RefPtr<AudioInitTask> init = new AudioInitTask(this, mLatencyRequest, params);
  init->Dispatch();
}
Example #26
0
void
BlobImplFile::GetType(nsAString& aType)
{
  aType.Truncate();

  if (mContentType.IsVoid()) {
    NS_ASSERTION(mWholeFile,
                 "Should only use lazy ContentType when using the whole file");

    if (!NS_IsMainThread()) {
      WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
      if (!workerPrivate) {
        // I have no idea in which thread this method is called. We cannot
        // return any valid value.
        return;
      }

      RefPtr<GetTypeRunnable> runnable =
        new GetTypeRunnable(workerPrivate, this);

      ErrorResult rv;
      runnable->Dispatch(rv);
      if (NS_WARN_IF(rv.Failed())) {
        rv.SuppressException();
      }
      return;
    }

    nsresult rv;
    nsCOMPtr<nsIMIMEService> mimeService =
      do_GetService(NS_MIMESERVICE_CONTRACTID, &rv);
    if (NS_WARN_IF(NS_FAILED(rv))) {
      return;
    }

    nsAutoCString mimeType;
    rv = mimeService->GetTypeFromFile(mFile, mimeType);
    if (NS_FAILED(rv)) {
      mimeType.Truncate();
    }

    AppendUTF8toUTF16(mimeType, mContentType);
    mContentType.SetIsVoid(false);
  }

  aType = mContentType;
}
Example #27
0
NS_IMETHODIMP
nsFileUploadContentStream::AsyncWait(nsIInputStreamCallback *callback,
                                     uint32_t flags, uint32_t count,
                                     nsIEventTarget *target)
{
  nsresult rv = nsBaseContentStream::AsyncWait(callback, flags, count, target);
  if (NS_FAILED(rv) || IsClosed())
    return rv;

  if (IsNonBlocking()) {
    nsCOMPtr<nsIRunnable> callback =
      NS_NewRunnableMethod(this, &nsFileUploadContentStream::OnCopyComplete);
    mCopyEvent->Dispatch(callback, mSink, target);
  }

  return NS_OK;
}
Example #28
0
/* static */ void
UiCompositorControllerChild::InitWithGPUProcess(RefPtr<nsThread> aThread,
                                                const uint64_t& aProcessToken,
                                                Endpoint<PUiCompositorControllerChild>&& aEndpoint)
{
  MOZ_ASSERT(!sChild);
  MOZ_ASSERT(!sParent);
  MOZ_ASSERT(aThread);
  MOZ_ASSERT(!sInitialized);

  sInitialized = true;
  RefPtr<UiCompositorControllerChild> child = new UiCompositorControllerChild(aThread, aProcessToken);

  RefPtr<nsIRunnable> task = NewRunnableMethod<Endpoint<PUiCompositorControllerChild>&&>(
    child, &UiCompositorControllerChild::OpenForGPUProcess, Move(aEndpoint));

  aThread->Dispatch(task.forget(), nsIThread::DISPATCH_NORMAL);
}
Example #29
0
void
AudioCallbackDriver::Revive()
{
    // Note: only called on MainThread, without monitor
    // We know were weren't in a running state
    STREAM_LOG(LogLevel::Debug, ("AudioCallbackDriver reviving."));
    // If we were switching, switch now. Otherwise, start the audio thread again.
    MonitorAutoLock mon(mGraphImpl->GetMonitor());
    if (mNextDriver) {
        mNextDriver->SetGraphTime(this, mIterationStart, mIterationEnd);
        mGraphImpl->SetCurrentDriver(mNextDriver);
        mNextDriver->Start();
    } else {
        STREAM_LOG(LogLevel::Debug, ("Starting audio threads for MediaStreamGraph %p from a new thread.", mGraphImpl));
        RefPtr<AsyncCubebTask> initEvent =
            new AsyncCubebTask(this, AsyncCubebOperation::INIT);
        initEvent->Dispatch();
    }
}
Example #30
0
    NS_IMETHOD Run()
    {
        MOZ_ASSERT(NS_IsMainThread());

        LIFECYCLE_LOG("MediaStreamGraphShutdownThreadRunnable for graph %p",
                      mDriver->GraphImpl());
        // We can't release an audio driver on the main thread, because it can be
        // blocking.
        if (mDriver->AsAudioCallbackDriver()) {
            LIFECYCLE_LOG("Releasing audio driver off main thread.");
            RefPtr<AsyncCubebTask> releaseEvent =
                new AsyncCubebTask(mDriver->AsAudioCallbackDriver(),
                                   AsyncCubebOperation::SHUTDOWN);
            mDriver = nullptr;
            releaseEvent->Dispatch();
        } else {
            LIFECYCLE_LOG("Dropping driver reference for SystemClockDriver.");
            mDriver = nullptr;
        }
        return NS_OK;
    }