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(); } } }
mozilla::ipc::IPCResult TestCancelParent::RecvDone() { MessageLoop::current()->PostTask(NewNonOwningRunnableMethod( "ipc::IToplevelProtocol::Close", this, &TestCancelParent::Close)); return IPC_OK(); }
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; }
void ProcessLink::SendClose() { mChan->AssertWorkerThread(); mChan->mMonitor->AssertCurrentThreadOwns(); mIOLoop->PostTask(NewNonOwningRunnableMethod(this, &ProcessLink::OnCloseChannel)); }
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(); }
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)); }
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)); } }
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; }
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 }
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; }
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)); } }