void GMPCDMCallbackProxy::SessionClosed(const nsCString& aSessionId) { MOZ_ASSERT(mProxy->IsOnOwnerThread()); bool keyStatusesChange = false; auto sid = NS_ConvertUTF8toUTF16(aSessionId); { CDMCaps::AutoLock caps(mProxy->Capabilites()); keyStatusesChange = caps.RemoveKeysForSession(NS_ConvertUTF8toUTF16(aSessionId)); } if (keyStatusesChange) { RefPtr<CDMProxy> proxy = mProxy; NS_DispatchToMainThread( NS_NewRunnableFunction([proxy, sid] () { proxy->OnKeyStatusesChange(sid); }) ); } RefPtr<CDMProxy> proxy = mProxy; NS_DispatchToMainThread( NS_NewRunnableFunction([proxy, sid] () { proxy->OnSessionClosed(sid); }) ); }
NotNull<AllocPolicy*> GlobalAllocPolicy::Instance(TrackType aTrack) { StaticMutexAutoLock lock(sMutex); if (aTrack == TrackType::kAudioTrack) { static RefPtr<AllocPolicyImpl> sAudioPolicy = []() { SystemGroup::Dispatch( TaskCategory::Other, NS_NewRunnableFunction( "GlobalAllocPolicy::GlobalAllocPolicy:Audio", []() { ClearOnShutdown(&sAudioPolicy, ShutdownPhase::ShutdownThreads); })); return new AllocPolicyImpl(MediaDecoderLimitDefault()); }(); return WrapNotNull(sAudioPolicy.get()); } static RefPtr<AllocPolicyImpl> sVideoPolicy = []() { SystemGroup::Dispatch( TaskCategory::Other, NS_NewRunnableFunction( "GlobalAllocPolicy::GlobalAllocPolicy:Audio", []() { ClearOnShutdown(&sVideoPolicy, ShutdownPhase::ShutdownThreads); })); return new AllocPolicyImpl(MediaDecoderLimitDefault()); }(); return WrapNotNull(sVideoPolicy.get()); }
mozilla::ipc::IProtocol* NuwaParent::CloneProtocol(Channel* aChannel, ProtocolCloneContext* aCtx) { MOZ_ASSERT(NS_IsMainThread()); RefPtr<NuwaParent> self = this; MonitorAutoLock lock(mMonitor); // Alloc NuwaParent on the worker thread. nsCOMPtr<nsIRunnable> runnable = NS_NewRunnableFunction([self] () -> void { MonitorAutoLock lock(self->mMonitor); // XXX Calling NuwaParent::Alloc() leads to a compilation error. Use // self->Alloc() as a workaround. self->mClonedActor = self->Alloc(); lock.Notify(); }); MOZ_ASSERT(runnable); MOZ_ALWAYS_TRUE(NS_SUCCEEDED(mWorkerThread->Dispatch(runnable, NS_DISPATCH_NORMAL))); while (!mClonedActor) { lock.Wait(); } RefPtr<NuwaParent> actor = mClonedActor; mClonedActor = nullptr; // mManager of the cloned actor is assigned after returning from this method. // We can't call ActorConstructed() right after Alloc() in the above runnable. // To be safe we dispatch a runnable to the current thread to do it. runnable = NS_NewRunnableFunction([actor] () -> void { MOZ_ASSERT(NS_IsMainThread()); nsCOMPtr<nsIRunnable> nested = NS_NewRunnableFunction([actor] () -> void { AssertIsOnBackgroundThread(); // Call NuwaParent::ActorConstructed() on the worker thread. actor->ActorConstructed(); // The actor can finally be deleted after fully constructed. mozilla::Unused << actor->Send__delete__(actor); }); MOZ_ASSERT(nested); MOZ_ALWAYS_TRUE(NS_SUCCEEDED( actor->mWorkerThread->Dispatch(nested, NS_DISPATCH_NORMAL))); }); MOZ_ASSERT(runnable); MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToMainThread(runnable))); return actor; }
void BenchmarkPlayback::DrainComplete() { RefPtr<Benchmark> ref(mMainThreadState); Dispatch(NS_NewRunnableFunction([this, ref]() { int32_t frames = mFrameCount - ref->mParameters.mStartupFrame; TimeDuration elapsedTime = TimeStamp::Now() - mDecodeStartTime; uint32_t decodeFps = frames / elapsedTime.ToSeconds(); MainThreadShutdown(); ref->Dispatch(NS_NewRunnableFunction([ref, decodeFps]() { ref->ReturnResult(decodeFps); })); })); }
// A single telemetry sample is reported for each MediaDataDecoder object // that has detected error or produced output successfully. static void SendTelemetry(unsigned long hr) { // Collapse the error codes into a range of 0-0xff that can be viewed in // telemetry histograms. For most MF_E_* errors, unique samples are used, // retaining the least significant 7 or 8 bits. Other error codes are // bucketed. uint32_t sample; if (SUCCEEDED(hr)) { sample = 0; } else if (hr < 0xc00d36b0) { sample = 1; // low bucket } else if (hr < 0xc00d3700) { sample = hr & 0xffU; // MF_E_* } else if (hr <= 0xc00d3705) { sample = 0x80 + (hr & 0xfU); // more MF_E_* } else if (hr < 0xc00d6d60) { sample = 2; // mid bucket } else if (hr <= 0xc00d6d78) { sample = hr & 0xffU; // MF_E_TRANSFORM_* } else { sample = 3; // high bucket } nsCOMPtr<nsIRunnable> runnable = NS_NewRunnableFunction( [sample] { Telemetry::Accumulate(Telemetry::MEDIA_WMF_DECODE_ERROR, sample); }); NS_DispatchToMainThread(runnable); }
/* static */ void IDecodingTask::NotifyDecodeComplete(NotNull<RasterImage*> aImage, NotNull<Decoder*> aDecoder) { MOZ_ASSERT(aDecoder->HasError() || !aDecoder->InFrame(), "Decode complete in the middle of a frame?"); // Capture the decoder's state. DecoderFinalStatus finalStatus = aDecoder->FinalStatus(); ImageMetadata metadata = aDecoder->GetImageMetadata(); DecoderTelemetry telemetry = aDecoder->Telemetry(); Progress progress = aDecoder->TakeProgress(); IntRect invalidRect = aDecoder->TakeInvalidRect(); Maybe<uint32_t> frameCount = aDecoder->TakeCompleteFrameCount(); SurfaceFlags surfaceFlags = aDecoder->GetSurfaceFlags(); // Synchronously notify if we can. if (NS_IsMainThread() && !(aDecoder->GetDecoderFlags() & DecoderFlags::ASYNC_NOTIFY)) { aImage->NotifyDecodeComplete(finalStatus, metadata, telemetry, progress, invalidRect, frameCount, surfaceFlags); return; } // We're forced to notify asynchronously. NotNull<RefPtr<RasterImage>> image = aImage; NS_DispatchToMainThread(NS_NewRunnableFunction([=]() -> void { image->NotifyDecodeComplete(finalStatus, metadata, telemetry, progress, invalidRect, frameCount, surfaceFlags); })); }
/* static */ void IDecodingTask::NotifyProgress(NotNull<RasterImage*> aImage, NotNull<Decoder*> aDecoder) { MOZ_ASSERT(aDecoder->HasProgress() && !aDecoder->IsMetadataDecode()); // Capture the decoder's state. If we need to notify asynchronously, it's // important that we don't wait until the lambda actually runs to capture the // state that we're going to notify. That would both introduce data races on // the decoder's state and cause inconsistencies between the NotifyProgress() // calls we make off-main-thread and the notifications that RasterImage // actually receives, which would cause bugs. Progress progress = aDecoder->TakeProgress(); IntRect invalidRect = aDecoder->TakeInvalidRect(); Maybe<uint32_t> frameCount = aDecoder->TakeCompleteFrameCount(); SurfaceFlags surfaceFlags = aDecoder->GetSurfaceFlags(); // Synchronously notify if we can. if (NS_IsMainThread() && !(aDecoder->GetDecoderFlags() & DecoderFlags::ASYNC_NOTIFY)) { aImage->NotifyProgress(progress, invalidRect, frameCount, surfaceFlags); return; } // We're forced to notify asynchronously. NotNull<RefPtr<RasterImage>> image = aImage; NS_DispatchToMainThread(NS_NewRunnableFunction([=]() -> void { image->NotifyProgress(progress, invalidRect, frameCount, surfaceFlags); })); }
/*static*/ void SmsManager::NotifySmsReceived(int32_t aId, jni::String::Param aSender, jni::String::Param aBody, int32_t aMessageClass, int64_t aSentTimestamp, int64_t aTimestamp) { // TODO Need to correct the message `threadId` parameter value. Bug 859098 SmsMessageData message; message.id() = aId; message.threadId() = 0; message.iccId() = EmptyString(); message.delivery() = eDeliveryState_Received; message.deliveryStatus() = eDeliveryStatus_Success; message.sender() = aSender ? aSender->ToString() : EmptyString(); message.receiver() = EmptyString(); message.body() = aBody ? aBody->ToString() : EmptyString(); message.messageClass() = static_cast<MessageClass>(aMessageClass); message.timestamp() = aTimestamp; message.sentTimestamp() = aSentTimestamp; message.deliveryTimestamp() = aTimestamp; message.read() = false; nsCOMPtr<nsIRunnable> runnable = NS_NewRunnableFunction([=] () { nsCOMPtr<nsIObserverService> obs = services::GetObserverService(); if (!obs) { return; } nsCOMPtr<nsISmsMessage> domMessage = new SmsMessageInternal(message); obs->NotifyObservers(domMessage, kSmsReceivedObserverTopic, nullptr); }); NS_DispatchToMainThread(runnable); }
already_AddRefed<Promise> PresentationReceiver::GetConnectionList(ErrorResult& aRv) { nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(mOwner); if (NS_WARN_IF(!global)) { aRv.Throw(NS_ERROR_UNEXPECTED); return nullptr; } if (!mGetConnectionListPromise) { mGetConnectionListPromise = Promise::Create(global, aRv); if (NS_WARN_IF(aRv.Failed())) { return nullptr; } RefPtr<PresentationReceiver> self = this; nsresult rv = NS_DispatchToMainThread(NS_NewRunnableFunction([self] () -> void { self->CreateConnectionList(); })); if (NS_FAILED(rv)) { aRv.Throw(rv); return nullptr; } } RefPtr<Promise> promise = mGetConnectionListPromise; return promise.forget(); }
void PDMFactory::EnsureInit() const { { StaticMutexAutoLock mon(sMonitor); if (sInstance) { // Quick exit if we already have an instance. return; } if (NS_IsMainThread()) { // On the main thread and holding the lock -> Create instance. sInstance = new PDMFactoryImpl(); ClearOnShutdown(&sInstance); return; } } // Not on the main thread -> Sync-dispatch creation to main thread. nsCOMPtr<nsIThread> mainThread = do_GetMainThread(); nsCOMPtr<nsIRunnable> runnable = NS_NewRunnableFunction([]() { StaticMutexAutoLock mon(sMonitor); if (!sInstance) { sInstance = new PDMFactoryImpl(); ClearOnShutdown(&sInstance); } }); SyncRunnable::DispatchToThread(mainThread, runnable); }
void GMPCDMCallbackProxy::BatchedKeyStatusChangedInternal(const nsCString& aSessionId, const nsTArray<CDMKeyInfo>& aKeyInfos) { bool keyStatusesChange = false; { CDMCaps::AutoLock caps(mProxy->Capabilites()); for (size_t i = 0; i < aKeyInfos.Length(); i++) { keyStatusesChange |= caps.SetKeyStatus(aKeyInfos[i].mKeyId, NS_ConvertUTF8toUTF16(aSessionId), aKeyInfos[i].mStatus); } } if (keyStatusesChange) { RefPtr<CDMProxy> proxy = mProxy; auto sid = NS_ConvertUTF8toUTF16(aSessionId); NS_DispatchToMainThread( NS_NewRunnableFunction([proxy, sid] () { proxy->OnKeyStatusesChange(sid); }) ); } }
void GMPCDMCallbackProxy::SessionError(const nsCString& aSessionId, nsresult aException, uint32_t aSystemCode, const nsCString& aMessage) { MOZ_ASSERT(mProxy->IsOnOwnerThread()); RefPtr<CDMProxy> proxy = mProxy; auto sid = NS_ConvertUTF8toUTF16(aSessionId); auto msg = NS_ConvertUTF8toUTF16(aMessage); NS_DispatchToMainThread( NS_NewRunnableFunction([proxy, sid, aException, aSystemCode, msg] () { proxy->OnSessionError(sid, aException, aSystemCode, msg); }) ); }
static void NotifyProgress(NotNull<Decoder*> aDecoder) { MOZ_ASSERT(aDecoder->HasProgress() && !aDecoder->IsMetadataDecode()); Progress progress = aDecoder->TakeProgress(); IntRect invalidRect = aDecoder->TakeInvalidRect(); Maybe<uint32_t> frameCount = aDecoder->TakeCompleteFrameCount(); SurfaceFlags surfaceFlags = aDecoder->GetSurfaceFlags(); // Synchronously notify if we can. if (NS_IsMainThread() && !(aDecoder->GetDecoderFlags() & DecoderFlags::ASYNC_NOTIFY)) { aDecoder->GetImage()->NotifyProgress(progress, invalidRect, frameCount, surfaceFlags); return; } // We're forced to notify asynchronously. NotNull<RefPtr<Decoder>> decoder = aDecoder; NS_DispatchToMainThread(NS_NewRunnableFunction([=]() -> void { decoder->GetImage()->NotifyProgress(progress, invalidRect, frameCount, surfaceFlags); })); }
RefPtr<GenericPromise> AutoplayRequest::RequestWithPrompt() { // If we've already requested permission, we'll just return the promise, // as we don't want to show multiple permission requests at once. // The promise is non-exclusive, so if the request has already completed, // the ThenValue will run immediately. if (mRequestDispatched) { PLAY_REQUEST_LOG( "AutoplayRequest %p RequestWithPrompt() request already dispatched", this); return mPromiseHolder.Ensure(__func__); } nsCOMPtr<nsPIDOMWindowInner> window = do_QueryReferent(mWindow); if (!window) { return GenericPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_NOT_ALLOWED_ERR, __func__); } nsCOMPtr<nsIContentPermissionRequest> request = do_QueryInterface(this); MOZ_RELEASE_ASSERT(request); nsCOMPtr<nsIRunnable> f = NS_NewRunnableFunction( "AutoplayRequest::RequestWithPrompt", [window, request]() { dom::nsContentPermissionUtils::AskPermission(request, window); }); mMainThreadTarget->Dispatch(f, NS_DISPATCH_NORMAL); mRequestDispatched = true; return mPromiseHolder.Ensure(__func__); }
void URL::CreateObjectURL(const GlobalObject& aGlobal, MediaSource& aSource, const objectURLOptions& aOptions, nsAString& aResult, ErrorResult& aError) { nsCOMPtr<nsIPrincipal> principal = nsContentUtils::ObjectPrincipal(aGlobal.Get()); nsCString url; nsresult rv = nsHostObjectProtocolHandler:: AddDataEntry(NS_LITERAL_CSTRING(MEDIASOURCEURI_SCHEME), &aSource, principal, url); if (NS_FAILED(rv)) { aError.Throw(rv); return; } nsCOMPtr<nsIRunnable> revocation = NS_NewRunnableFunction( [url] { nsHostObjectProtocolHandler::RemoveDataEntry(url); }); nsContentUtils::RunInStableState(revocation.forget()); CopyASCIItoUTF16(url, aResult); }
void BenchmarkPlayback::DemuxNextSample() { MOZ_ASSERT(OnThread()); RefPtr<Benchmark> ref(mGlobalState); RefPtr<MediaTrackDemuxer::SamplesPromise> promise = mTrackDemuxer->GetSamples(); promise->Then( Thread(), __func__, [this, ref](RefPtr<MediaTrackDemuxer::SamplesHolder> aHolder) { mSamples.AppendElements(std::move(aHolder->mSamples)); if (ref->mParameters.mStopAtFrame && mSamples.Length() == ref->mParameters.mStopAtFrame.ref()) { InitDecoder(std::move(*mTrackDemuxer->GetInfo())); } else { Dispatch( NS_NewRunnableFunction("BenchmarkPlayback::DemuxNextSample", [this, ref]() { DemuxNextSample(); })); } }, [this, ref](const MediaResult& aError) { switch (aError.Code()) { case NS_ERROR_DOM_MEDIA_END_OF_STREAM: InitDecoder(std::move(*mTrackDemuxer->GetInfo())); break; default: Error(aError); break; } }); }
void MediaDecodeTask::OnMetadataRead(MetadataHolder* aMetadata) { mMediaInfo = aMetadata->mInfo; if (!mMediaInfo.HasAudio()) { mDecoderReader->Shutdown(); ReportFailureOnMainThread(WebAudioDecodeJob::NoAudio); return; } nsCString codec; if (!mMediaInfo.mAudio.GetAsAudioInfo()->mMimeType.IsEmpty()) { codec = nsPrintfCString("webaudio; %s", mMediaInfo.mAudio.GetAsAudioInfo()->mMimeType.get()); } else { codec = nsPrintfCString("webaudio;resource; %s", mContentType.get()); } nsCOMPtr<nsIRunnable> task = NS_NewRunnableFunction([codec]() -> void { MOZ_ASSERT(!codec.IsEmpty()); MOZ_LOG(gMediaDecoderLog, LogLevel::Debug, ("Telemetry (WebAudio) MEDIA_CODEC_USED= '%s'", codec.get())); Telemetry::Accumulate(Telemetry::ID::MEDIA_CODEC_USED, codec); }); AbstractThread::MainThread()->Dispatch(task.forget()); RequestSample(); }
/* static */ void URLMainThread::CreateObjectURL(const GlobalObject& aGlobal, MediaSource& aSource, const objectURLOptions& aOptions, nsAString& aResult, ErrorResult& aRv) { MOZ_ASSERT(NS_IsMainThread()); nsCOMPtr<nsIPrincipal> principal = nsContentUtils::ObjectPrincipal(aGlobal.Get()); nsAutoCString url; aRv = nsHostObjectProtocolHandler::AddDataEntry(&aSource, principal, url); if (NS_WARN_IF(aRv.Failed())) { return; } nsCOMPtr<nsIRunnable> revocation = NS_NewRunnableFunction( [url] { nsHostObjectProtocolHandler::RemoveDataEntry(url); }); nsContentUtils::RunInStableState(revocation.forget()); CopyASCIItoUTF16(url, aResult); }
void DecodedAudioDataSink::Shutdown() { { ReentrantMonitorAutoEnter mon(GetReentrantMonitor()); if (mAudioStream) { mAudioStream->Cancel(); } } nsRefPtr<DecodedAudioDataSink> self = this; nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction([=] () { self->mStopAudioThread = true; if (!self->mAudioLoopScheduled) { self->AudioLoop(); } }); DispatchTask(r.forget()); mThread->Shutdown(); mThread = nullptr; if (mAudioStream) { mAudioStream->Shutdown(); mAudioStream = nullptr; } // Should've reached the final state after shutdown. MOZ_ASSERT(mState == AUDIOSINK_STATE_SHUTDOWN || mState == AUDIOSINK_STATE_ERROR); // Should have no pending state change. MOZ_ASSERT(mPendingState.isNothing()); }
status_t FakeSurfaceComposer::getDisplayConfigs(const sp<IBinder>& display, Vector<DisplayInfo>* configs) { if (configs == NULL) { return BAD_VALUE; } // Limit DisplayConfigs only to primary display if (!display.get() || display != mPrimaryDisplay) { return NAME_NOT_FOUND; } configs->clear(); DisplayInfo info = DisplayInfo(); nsCOMPtr<nsIRunnable> runnable = NS_NewRunnableFunction([&]() { MOZ_ASSERT(NS_IsMainThread()); getPrimaryDisplayInfo(&info); }); NS_DispatchToMainThread(runnable, NS_DISPATCH_SYNC); configs->push_back(info); return NO_ERROR; }
void PaintThread::PaintContents(CapturedPaintState* aState, PrepDrawTargetForPaintingCallback aCallback) { MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(aState); // If painting asynchronously, we need to acquire the compositor bridge which // owns the underlying MessageChannel. Otherwise we leave it null and use // synchronous dispatch. RefPtr<CompositorBridgeChild> cbc; if (!gfxPrefs::LayersOMTPForceSync()) { cbc = CompositorBridgeChild::Get(); cbc->NotifyBeginAsyncPaint(aState); } RefPtr<CapturedPaintState> state(aState); RefPtr<DrawTargetCapture> capture(aState->mCapture); RefPtr<PaintThread> self = this; RefPtr<Runnable> task = NS_NewRunnableFunction("PaintThread::PaintContents", [self, cbc, capture, state, aCallback]() -> void { self->PaintContentsAsync(cbc, state, aCallback); }); if (cbc) { sThread->Dispatch(task.forget()); } else { SyncRunnable::DispatchToThread(sThread, task); } }
NS_IMETHODIMP PresentationService::UntrackSessionInfo(const nsAString& aSessionId, uint8_t aRole) { PRES_DEBUG("%s:id[%s], role[%d]\n", __func__, NS_ConvertUTF16toUTF8(aSessionId).get(), aRole); MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER || aRole == nsIPresentationService::ROLE_RECEIVER); // Remove the session info. if (nsIPresentationService::ROLE_CONTROLLER == aRole) { mSessionInfoAtController.Remove(aSessionId); } else { // Terminate receiver page. uint64_t windowId; nsresult rv = GetWindowIdBySessionIdInternal(aSessionId, aRole, &windowId); if (NS_SUCCEEDED(rv)) { NS_DispatchToMainThread(NS_NewRunnableFunction([windowId]() -> void { PRES_DEBUG("Attempt to close window[%d]\n", windowId); if (auto* window = nsGlobalWindow::GetInnerWindowWithId(windowId)) { window->Close(); } })); } mSessionInfoAtReceiver.Remove(aSessionId); } // Remove the in-process responding info if there's still any. RemoveRespondingSessionId(aSessionId, aRole); return NS_OK; }
nsresult GMPVideoDecoderParent::Reset() { LOGD(("GMPVideoDecoderParent[%p]::Reset()", this)); if (!mIsOpen) { NS_WARNING("Trying to use an dead GMP video decoder"); return NS_ERROR_FAILURE; } MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread()); if (!SendReset()) { return NS_ERROR_FAILURE; } mIsAwaitingResetComplete = true; RefPtr<GMPVideoDecoderParent> self(this); nsCOMPtr<nsIRunnable> task = NS_NewRunnableFunction([self]() -> void { LOGD(("GMPVideoDecoderParent[%p]::ResetCompleteTimeout() timed out waiting for ResetComplete", self.get())); self->mResetCompleteTimeout = nullptr; LogToBrowserConsole(NS_LITERAL_STRING("GMPVideoDecoderParent timed out waiting for ResetComplete()")); }); CancelResetCompleteTimeout(); mResetCompleteTimeout = SimpleTimer::Create(task, 5000, mPlugin->GMPThread()); // Async IPC, we don't have access to a return value. return NS_OK; }
void BenchmarkPlayback::DemuxNextSample() { MOZ_ASSERT(OnThread()); RefPtr<Benchmark> ref(mMainThreadState); RefPtr<MediaTrackDemuxer::SamplesPromise> promise = mTrackDemuxer->GetSamples(); promise->Then( Thread(), __func__, [this, ref](RefPtr<MediaTrackDemuxer::SamplesHolder> aHolder) { mSamples.AppendElements(Move(aHolder->mSamples)); if (ref->mParameters.mStopAtFrame && mSamples.Length() == (size_t)ref->mParameters.mStopAtFrame.ref()) { InitDecoder(Move(*mTrackDemuxer->GetInfo())); } else { Dispatch(NS_NewRunnableFunction([this, ref]() { DemuxNextSample(); })); } }, [this, ref](DemuxerFailureReason aReason) { switch (aReason) { case DemuxerFailureReason::END_OF_STREAM: InitDecoder(Move(*mTrackDemuxer->GetInfo())); break; default: MainThreadShutdown(); } }); }
void ClientLayerManager::Destroy() { // It's important to call ClearCachedResource before Destroy because the // former will early-return if the later has already run. ClearCachedResources(); LayerManager::Destroy(); if (mTransactionIdAllocator) { // Make sure to notify the refresh driver just in case it's waiting on a // pending transaction. Do this at the top of the event loop so we don't // cause a paint to occur during compositor shutdown. RefPtr<TransactionIdAllocator> allocator = mTransactionIdAllocator; uint64_t id = mLatestTransactionId; RefPtr<Runnable> task = NS_NewRunnableFunction( "TransactionIdAllocator::NotifyTransactionCompleted", [allocator, id] () -> void { allocator->NotifyTransactionCompleted(id); }); NS_DispatchToMainThread(task.forget()); } // Forget the widget pointer in case we outlive our owning widget. mWidget = nullptr; }
void BenchmarkPlayback::Error(MediaDataDecoderError aError) { RefPtr<Benchmark> ref(mMainThreadState); Dispatch(NS_NewRunnableFunction([this, ref]() { MainThreadShutdown(); })); }
nsresult U2FSoftTokenManager::GetOrCreateWrappingKey(const UniquePK11SlotInfo& aSlot, const nsNSSShutDownPreventionLock& locker) { MOZ_ASSERT(aSlot); if (NS_WARN_IF(!aSlot)) { return NS_ERROR_INVALID_ARG; } // Search for an existing wrapping key. If we find it, // store it for later and mark ourselves initialized. mWrappingKey = GetSymKeyByNickname(aSlot, mSecretNickname, locker); if (mWrappingKey) { MOZ_LOG(gNSSTokenLog, LogLevel::Debug, ("U2F Soft Token Key found.")); mInitialized = true; return NS_OK; } MOZ_LOG(gNSSTokenLog, LogLevel::Info, ("No keys found. Generating new U2F Soft Token wrapping key.")); // We did not find an existing wrapping key, so we generate one in the // persistent database (e.g, Token). mWrappingKey = UniquePK11SymKey( PK11_TokenKeyGenWithFlags(aSlot.get(), CKM_AES_KEY_GEN, /* default params */ nullptr, kWrappingKeyByteLen, /* empty keyid */ nullptr, /* flags */ CKF_WRAP | CKF_UNWRAP, /* attributes */ PK11_ATTR_TOKEN | PK11_ATTR_PRIVATE, /* wincx */ nullptr)); if (NS_WARN_IF(!mWrappingKey)) { MOZ_LOG(gNSSTokenLog, LogLevel::Warning, ("Failed to store wrapping key, NSS error #%d", PORT_GetError())); return NS_ERROR_FAILURE; } SECStatus srv = PK11_SetSymKeyNickname(mWrappingKey.get(), mSecretNickname.get()); if (NS_WARN_IF(srv != SECSuccess)) { MOZ_LOG(gNSSTokenLog, LogLevel::Warning, ("Failed to set nickname, NSS error #%d", PORT_GetError())); return NS_ERROR_FAILURE; } MOZ_LOG(gNSSTokenLog, LogLevel::Debug, ("Key stored, nickname set to %s.", mSecretNickname.get())); AbstractThread::MainThread()->Dispatch(NS_NewRunnableFunction( [] () { MOZ_ASSERT(NS_IsMainThread()); Preferences::SetUint(PREF_U2F_NSSTOKEN_COUNTER, 0); })); return NS_OK; }
void Forget() { mAbstractMainThread->Dispatch(NS_NewRunnableFunction([this] () { MOZ_ASSERT(NS_IsMainThread()); mFinishPromise.ResolveIfExists(true, __func__); })); MutexAutoLock lock(mMutex); mStream = nullptr; }
RefPtr<Benchmark::BenchmarkPromise> Benchmark::Run() { RefPtr<BenchmarkPromise> p = mPromise.Ensure(__func__); RefPtr<Benchmark> self = this; mPlaybackState.Dispatch( NS_NewRunnableFunction([self]() { self->mPlaybackState.DemuxSamples(); })); return p; }
/* static */ void CompositorManagerParent::Shutdown() { MOZ_ASSERT(NS_IsMainThread()); #ifdef COMPOSITOR_MANAGER_PARENT_EXPLICIT_SHUTDOWN CompositorThreadHolder::Loop()->PostTask(NS_NewRunnableFunction( "layers::CompositorManagerParent::Shutdown", []() -> void { CompositorManagerParent::ShutdownInternal(); })); #endif }