Decoder::~Decoder() { MOZ_ASSERT(mProgress == NoProgress || !mImage, "Destroying Decoder without taking all its progress changes"); MOZ_ASSERT(mInvalidRect.IsEmpty() || !mImage, "Destroying Decoder without taking all its invalidations"); mInitialized = false; if (mImage && !NS_IsMainThread()) { // Dispatch mImage to main thread to prevent it from being destructed by the // decode thread. NS_ReleaseOnMainThread(mImage.forget()); } }
void DecodedSurfaceProvider::DropImageReference() { if (!mImage) { return; // Nothing to do. } // RasterImage objects need to be destroyed on the main thread. We also need // to destroy them asynchronously, because if our surface cache entry is // destroyed and we were the only thing keeping |mImage| alive, RasterImage's // destructor may call into the surface cache while whatever code caused us to // get evicted is holding the surface cache lock, causing deadlock. RefPtr<RasterImage> image = mImage; mImage = nullptr; NS_ReleaseOnMainThread(image.forget(), /* aAlwaysProxy = */ true); }
void ServiceWorkerJob::Finish(ErrorResult& aRv) { AssertIsOnMainThread(); MOZ_ASSERT(mState == State::Started); // Ensure that we only surface SecurityErr, TypeErr or InvalidStateErr to script. if (aRv.Failed() && !aRv.ErrorCodeIs(NS_ERROR_DOM_SECURITY_ERR) && !aRv.ErrorCodeIs(NS_ERROR_DOM_TYPE_ERR) && !aRv.ErrorCodeIs(NS_ERROR_DOM_INVALID_STATE_ERR)) { // Remove the old error code so we can replace it with a TypeError. aRv.SuppressException(); NS_ConvertUTF8toUTF16 scriptSpec(mScriptSpec); NS_ConvertUTF8toUTF16 scope(mScope); // Throw the type error with a generic error message. aRv.ThrowTypeError<MSG_SW_INSTALL_ERROR>(scriptSpec, scope); } // The final callback may drop the last ref to this object. RefPtr<ServiceWorkerJob> kungFuDeathGrip = this; if (!mResultCallbacksInvoked) { InvokeResultCallbacks(aRv); } mState = State::Finished; mFinalCallback->JobFinished(this, aRv); mFinalCallback = nullptr; // The callback might not consume the error. aRv.SuppressException(); // Async release this object to ensure that our caller methods complete // as well. NS_ReleaseOnMainThread(kungFuDeathGrip.forget(), true /* always proxy */); }
/** * Free all used memory and close stream. */ NS_IMETHODIMP nsGIOInputStream::Close() { if (mStream) { g_object_unref(mStream); mStream = nullptr; } if (mHandle) { g_object_unref(mHandle); mHandle = nullptr; } if (mDirList) { // Destroy the list of GIOFileInfo objects... g_list_foreach(mDirList, (GFunc) g_object_unref, nullptr); g_list_free(mDirList); mDirList = nullptr; mDirListPtr = nullptr; } if (mChannel) { NS_ReleaseOnMainThread(dont_AddRef(mChannel)); mChannel = nullptr; } mSpec.Truncate(); // free memory // Prevent future reads from re-opening the handle. if (NS_SUCCEEDED(mStatus)) mStatus = NS_BASE_STREAM_CLOSED; return NS_OK; }
nsBaseChannel::~nsBaseChannel() { NS_ReleaseOnMainThread(mLoadInfo.forget()); }
nsBaseChannel::~nsBaseChannel() { NS_ReleaseOnMainThread(mLoadInfo); }
void FakeSurfaceComposer::captureScreenImp(const sp<IGraphicBufferProducer>& producer, uint32_t reqWidth, uint32_t reqHeight, const sp<GraphicProducerWrapper>& wrapper) { MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(wrapper.get()); RefPtr<nsScreenGonk> screen = nsScreenManagerGonk::GetPrimaryScreen(); // get screen geometry nsIntRect screenBounds = screen->GetNaturalBounds().ToUnknownRect(); const uint32_t hw_w = screenBounds.width; const uint32_t hw_h = screenBounds.height; if (reqWidth > hw_w || reqHeight > hw_h) { ALOGE("size mismatch (%d, %d) > (%d, %d)", reqWidth, reqHeight, hw_w, hw_h); static_cast<GraphicProducerWrapper*>(producer->asBinder().get())->exit(BAD_VALUE); return; } reqWidth = (!reqWidth) ? hw_w : reqWidth; reqHeight = (!reqHeight) ? hw_h : reqHeight; nsScreenGonk* screenPtr = screen.forget().take(); nsCOMPtr<nsIRunnable> runnable = NS_NewRunnableFunction([screenPtr, reqWidth, reqHeight, producer, wrapper]() { // create a surface (because we're a producer, and we need to // dequeue/queue a buffer) sp<Surface> sur = new Surface(producer); ANativeWindow* window = sur.get(); if (native_window_api_connect(window, NATIVE_WINDOW_API_EGL) != NO_ERROR) { static_cast<GraphicProducerWrapper*>(producer->asBinder().get())->exit(BAD_VALUE); NS_ReleaseOnMainThread(screenPtr); return; } uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE; int err = 0; err = native_window_set_buffers_dimensions(window, reqWidth, reqHeight); err |= native_window_set_scaling_mode(window, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW); err |= native_window_set_buffers_format(window, HAL_PIXEL_FORMAT_RGBA_8888); err |= native_window_set_usage(window, usage); status_t result = NO_ERROR; if (err == NO_ERROR) { ANativeWindowBuffer* buffer; result = native_window_dequeue_buffer_and_wait(window, &buffer); if (result == NO_ERROR) { nsresult rv = screenPtr->MakeSnapshot(buffer); if (rv != NS_OK) { result = INVALID_OPERATION; } window->queueBuffer(window, buffer, -1); } } else { result = BAD_VALUE; } native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL); static_cast<GraphicProducerWrapper*>(producer->asBinder().get())->exit(result); NS_ReleaseOnMainThread(screenPtr); }); mozilla::layers::CompositorParent::CompositorLoop()->PostTask( FROM_HERE, new RunnableCallTask(runnable)); }
~nsWyciwygAsyncEvent() { NS_ReleaseOnMainThread(mChannel.forget()); }
nsWyciwygChannel::~nsWyciwygChannel() { if (mLoadInfo) { NS_ReleaseOnMainThread(mLoadInfo.forget(), false); } }