~AsyncInitDatabase() { NS_ReleaseOnMainThreadSystemGroup( "AsyncInitDatabase::mStorageFile", mStorageFile.forget()); NS_ReleaseOnMainThreadSystemGroup( "AsyncInitDatabase::mConnection", mConnection.forget()); // Generally, the callback will be released by CallbackComplete. // However, if for some reason Run() is not executed, we still // need to ensure that it is released here. NS_ReleaseOnMainThreadSystemGroup( "AsyncInitDatabase::mCallback", mCallback.forget()); }
NS_IMETHOD Run() override { nsresult res; MOZ_ASSERT(!NS_IsMainThread()); { mozilla::MonitorAutoLock mon(mDict->mMonitorSave); nsCOMPtr<nsIOutputStream> outStream; NS_NewSafeLocalFileOutputStream(getter_AddRefs(outStream), mFile, PR_CREATE_FILE | PR_WRONLY | PR_TRUNCATE, 0664); // Get a buffered output stream 4096 bytes big, to optimize writes. nsCOMPtr<nsIOutputStream> bufferedOutputStream; res = NS_NewBufferedOutputStream(getter_AddRefs(bufferedOutputStream), outStream.forget(), 4096); if (NS_FAILED(res)) { return res; } uint32_t bytesWritten; nsAutoCString utf8Key; for (uint32_t i = 0; i < mDictWords.Length(); ++i) { CopyUTF16toUTF8(mDictWords[i], utf8Key); bufferedOutputStream->Write(utf8Key.get(), utf8Key.Length(), &bytesWritten); bufferedOutputStream->Write("\n", 1, &bytesWritten); } nsCOMPtr<nsISafeOutputStream> safeStream = do_QueryInterface(bufferedOutputStream); NS_ASSERTION(safeStream, "expected a safe output stream!"); if (safeStream) { res = safeStream->Finish(); if (NS_FAILED(res)) { NS_WARNING("failed to save personal dictionary file! possible data loss"); } } // Save is done, reset the state variable and notify those who are waiting. mDict->mSavePending = false; mon.Notify(); // Leaving the block where 'mon' was declared will call the destructor // and unlock. } // Release the dictionary on the main thread. NS_ReleaseOnMainThreadSystemGroup( "mozPersonalDictionarySave::mDict", mDict.forget().downcast<mozIPersonalDictionary>()); return NS_OK; }
NS_IMETHOD Run() override { mDict->SyncLoad(); // Release the dictionary on the main thread NS_ReleaseOnMainThreadSystemGroup( "mozPersonalDictionaryLoader::mDict", mDict.forget().downcast<mozIPersonalDictionary>()); return NS_OK; }
void AnimationSurfaceProvider::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_ReleaseOnMainThreadSystemGroup(image.forget(), /* aAlwaysProxy = */ true); }
/** * 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_ReleaseOnMainThreadSystemGroup( "nsGIOInputStream::mChannel", 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; }