コード例 #1
0
void 
ProcessLink::Open(mozilla::ipc::Transport* aTransport, MessageLoop *aIOLoop, Side aSide)
{
    NS_PRECONDITION(aTransport, "need transport layer");

    // FIXME need to check for valid channel

    mTransport = aTransport;

    // FIXME figure out whether we're in parent or child, grab IO loop
    // appropriately
    bool needOpen = true;
    if(aIOLoop) {
        // We're a child or using the new arguments.  Either way, we
        // need an open.
        needOpen = true;
        mChan->mSide = (aSide == UnknownSide) ? ChildSide : aSide;
    } else {
        NS_PRECONDITION(aSide == UnknownSide, "expected default side arg");

        // parent
        mChan->mSide = ParentSide;
        needOpen = false;
        aIOLoop = XRE_GetIOMessageLoop();
    }

    mIOLoop = aIOLoop;

    NS_ASSERTION(mIOLoop, "need an IO loop");
    NS_ASSERTION(mChan->mWorkerLoop, "need a worker loop");

    {
        MonitorAutoLock lock(*mChan->mMonitor);

        if (needOpen) {
            // Transport::Connect() has not been called.  Call it so
            // we start polling our pipe and processing outgoing
            // messages.
            mIOLoop->PostTask(NewNonOwningRunnableMethod(this, &ProcessLink::OnChannelOpened));
        } else {
            // Transport::Connect() has already been called.  Take
            // over the channel from the previous listener and process
            // any queued messages.
            mIOLoop->PostTask(NewNonOwningRunnableMethod(this, &ProcessLink::OnTakeConnectedChannel));
        }

        // Should not wait here if something goes wrong with the channel.
        while (!mChan->Connected() && mChan->mChannelState != ChannelError) {
            mChan->mMonitor->Wait();
        }
    }
}
コード例 #2
0
ファイル: TestCancel.cpp プロジェクト: luke-chang/gecko-1
mozilla::ipc::IPCResult
TestCancelParent::RecvDone()
{
  MessageLoop::current()->PostTask(NewNonOwningRunnableMethod(
    "ipc::IToplevelProtocol::Close", this, &TestCancelParent::Close));
  return IPC_OK();
}
コード例 #3
0
LazyIdleThread::Release()
{
  nsrefcnt count = --mRefCnt;
  NS_LOG_RELEASE(this, count, "LazyIdleThread");

  if (!count) {
    // Stabilize refcount.
    mRefCnt = 1;

    nsCOMPtr<nsIRunnable> runnable =
      NewNonOwningRunnableMethod(this, &LazyIdleThread::SelfDestruct);
    NS_WARNING_ASSERTION(runnable, "Couldn't make runnable!");

    if (NS_FAILED(NS_DispatchToCurrentThread(runnable))) {
      MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
      // The only way this could fail is if we're in shutdown, and in that case
      // threads should have been joined already. Deleting here isn't dangerous
      // anymore because we won't spin the event loop waiting to join the
      // thread.
      SelfDestruct();
    }
  }

  return count;
}
コード例 #4
0
void
ProcessLink::SendClose()
{
    mChan->AssertWorkerThread();
    mChan->mMonitor->AssertCurrentThreadOwns();

    mIOLoop->PostTask(NewNonOwningRunnableMethod(this, &ProcessLink::OnCloseChannel));
}
コード例 #5
0
mozilla::ipc::IPCResult
TestInterruptShutdownRaceParent::RecvStartDeath()
{
    // this will be ordered before the OnMaybeDequeueOne event of
    // Orphan in the queue
    MessageLoop::current()->PostTask(
        NewNonOwningRunnableMethod(this,
				   &TestInterruptShutdownRaceParent::StartShuttingDown));
    return IPC_OK();
}
コード例 #6
0
void FunctionBrokerChild::ActorDestroy(ActorDestroyReason aWhy) {
  MOZ_ASSERT(mThread->IsOnThread());

  // Queue up a task on the PD thread.  When that task is executed then
  // we know that anything queued before ActorDestroy has completed.
  // At that point, we can set mShutdownDone and alert any waiting
  // threads that it is safe to destroy us.
  sInstance->PostToDispatchThread(NewNonOwningRunnableMethod(
      "FunctionBrokerChild::ShutdownOnDispatchThread", sInstance,
      &FunctionBrokerChild::ShutdownOnDispatchThread));
}
コード例 #7
0
ファイル: GMPCrashHelper.cpp プロジェクト: bgrins/gecko-dev
void
GMPCrashHelper::Destroy()
{
  if (NS_IsMainThread()) {
    delete this;
  } else {
    // Don't addref, as then we'd end up releasing after the detele runs!
    SystemGroup::Dispatch(TaskCategory::Other,
                          NewNonOwningRunnableMethod("GMPCrashHelper::Destroy",
                                                     this,
                                                     &GMPCrashHelper::Destroy));
  }
}
コード例 #8
0
bool
TestBridgeMainSubChild::RecvHi()
{
    if (!SendHelloSync())
        fail("sending HelloSync");
    if (!CallHelloRpc())
        fail("calling HelloRpc");
    if (!mGotHi)
        fail("didn't answer HiRpc");

    // Need to close the channel without message-processing frames on
    // the C++ stack
    MessageLoop::current()->PostTask(
        NewNonOwningRunnableMethod(this, &TestBridgeMainSubChild::Close));
    return true;
}
コード例 #9
0
void
StorageDBThread::NotifyFlushCompletion()
{
#ifdef DOM_STORAGE_TESTS
  if (!NS_IsMainThread()) {
    RefPtr<nsRunnableMethod<StorageDBThread, void, false> > event =
      NewNonOwningRunnableMethod(this, &StorageDBThread::NotifyFlushCompletion);
    NS_DispatchToMainThread(event);
    return;
  }

  nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
  if (obs) {
    obs->NotifyObservers(nullptr, "domstorage-test-flushed", nullptr);
  }
#endif
}
コード例 #10
0
ファイル: TestHangs.cpp プロジェクト: MichaelKohler/gecko-dev
bool
TestHangsParent::ShouldContinueFromReplyTimeout()
{
    mDetectedHang = true;

    // so we've detected a timeout after 2 ms ... now we cheat and
    // sleep for a long time, to allow the subprocess's reply to come
    // in

    PR_Sleep(5000);

    // reply should be here; we'll post a task to shut things down.
    // This must be after OnMaybeDequeueOne() in the event queue.
    MessageLoop::current()->PostTask(
        NewNonOwningRunnableMethod(this, &TestHangsParent::CleanUp));

    GetIPCChannel()->CloseWithTimeout();

    return false;
}
コード例 #11
0
ReverbConvolver::ReverbConvolver(const float* impulseResponseData,
                                 size_t impulseResponseLength,
                                 size_t maxFFTSize,
                                 size_t convolverRenderPhase,
                                 bool useBackgroundThreads)
    : m_impulseResponseLength(impulseResponseLength)
    , m_accumulationBuffer(impulseResponseLength + WEBAUDIO_BLOCK_SIZE)
    , m_inputBuffer(InputBufferSize)
    , m_backgroundThread("ConvolverWorker")
    , m_backgroundThreadCondition(&m_backgroundThreadLock)
    , m_useBackgroundThreads(useBackgroundThreads)
    , m_wantsToExit(false)
    , m_moreInputBuffered(false)
{
    // For the moment, a good way to know if we have real-time constraint is to check if we're using background threads.
    // Otherwise, assume we're being run from a command-line tool.
    bool hasRealtimeConstraint = useBackgroundThreads;

    const float* response = impulseResponseData;
    size_t totalResponseLength = impulseResponseLength;

    // The total latency is zero because the first FFT stage is small enough
    // to return output in the first block.
    size_t reverbTotalLatency = 0;

    size_t stageOffset = 0;
    size_t stagePhase = 0;
    size_t fftSize = MinFFTSize;
    while (stageOffset < totalResponseLength) {
        size_t stageSize = fftSize / 2;

        // For the last stage, it's possible that stageOffset is such that we're straddling the end
        // of the impulse response buffer (if we use stageSize), so reduce the last stage's length...
        if (stageSize + stageOffset > totalResponseLength) {
            stageSize = totalResponseLength - stageOffset;
            // Use smallest FFT that is large enough to cover the last stage.
            fftSize = MinFFTSize;
            while (stageSize * 2 > fftSize) {
              fftSize *= 2;
            }
        }

        // This "staggers" the time when each FFT happens so they don't all happen at the same time
        int renderPhase = convolverRenderPhase + stagePhase;

        nsAutoPtr<ReverbConvolverStage> stage
          (new ReverbConvolverStage(response, totalResponseLength,
                                    reverbTotalLatency, stageOffset, stageSize,
                                    fftSize, renderPhase,
                                    &m_accumulationBuffer));

        bool isBackgroundStage = false;

        if (this->useBackgroundThreads() && stageOffset > RealtimeFrameLimit) {
            m_backgroundStages.AppendElement(stage.forget());
            isBackgroundStage = true;
        } else
            m_stages.AppendElement(stage.forget());

        // Figure out next FFT size
        fftSize *= 2;

        stageOffset += stageSize;

        if (hasRealtimeConstraint && !isBackgroundStage
            && fftSize > MaxRealtimeFFTSize) {
            fftSize = MaxRealtimeFFTSize;
            // Custom phase positions for all but the first of the realtime
            // stages of largest size.  These spread out the work of the
            // larger realtime stages.  None of the FFTs of size 1024, 2048 or
            // 4096 are performed when processing the same block.  The first
            // MaxRealtimeFFTSize = 4096 stage, at the end of the doubling,
            // performs its FFT at block 7.  The FFTs of size 2048 are
            // performed in blocks 3 + 8 * n and size 1024 at 1 + 4 * n.
            const uint32_t phaseLookup[] = { 14, 0, 10, 4 };
            stagePhase = WEBAUDIO_BLOCK_SIZE *
                phaseLookup[m_stages.Length() % ArrayLength(phaseLookup)];
        } else if (fftSize > maxFFTSize) {
            fftSize = maxFFTSize;
            // A prime offset spreads out FFTs in a way that all
            // available phase positions will be used if there are sufficient
            // stages.
            stagePhase += 5 * WEBAUDIO_BLOCK_SIZE;
        } else if (stageSize > WEBAUDIO_BLOCK_SIZE) {
            // As the stages are doubling in size, the next FFT will occur
            // mid-way between FFTs for this stage.
            stagePhase = stageSize - WEBAUDIO_BLOCK_SIZE;
        }
    }

    // Start up background thread
    // FIXME: would be better to up the thread priority here.  It doesn't need to be real-time, but higher than the default...
    if (this->useBackgroundThreads() && m_backgroundStages.Length() > 0) {
        if (!m_backgroundThread.Start()) {
          NS_WARNING("Cannot start convolver thread.");
          return;
        }
        m_backgroundThread.message_loop()->PostTask(NewNonOwningRunnableMethod(this,
									       &ReverbConvolver::backgroundThreadEntry));
    }
}