From 5580668495fbdc6495c8ef5e58f1e1b41c04a87b Mon Sep 17 00:00:00 2001 From: Jan-Ivar Bruaroey Date: Thu, 14 May 2015 07:30:51 -0400 Subject: [PATCH] Bug 1162720 - enumerateDevices visits main thread for profileDir. r=jesup --- dom/media/systemservices/MediaParent.cpp | 118 +++++++++++++++++------ dom/media/systemservices/MediaUtils.h | 56 +---------- 2 files changed, 89 insertions(+), 85 deletions(-) diff --git a/dom/media/systemservices/MediaParent.cpp b/dom/media/systemservices/MediaParent.cpp index 5239233afb2..633b1763ccc 100644 --- a/dom/media/systemservices/MediaParent.cpp +++ b/dom/media/systemservices/MediaParent.cpp @@ -104,10 +104,7 @@ class ParentSingleton : public nsISupports class OriginKeysLoader : public OriginKeysTable { public: - OriginKeysLoader() - { - Load(); - } + OriginKeysLoader() {} nsresult GetOriginKey(const nsACString& aOrigin, nsCString& result) @@ -123,13 +120,7 @@ class ParentSingleton : public nsISupports already_AddRefed GetFile() { - if (!mProfileDir) { - nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, - getter_AddRefs(mProfileDir)); - if (NS_WARN_IF(NS_FAILED(rv))) { - return nullptr; - } - } + MOZ_ASSERT(mProfileDir); nsCOMPtr file; nsresult rv = mProfileDir->Clone(getter_AddRefs(file)); if (NS_WARN_IF(NS_FAILED(rv))) { @@ -317,6 +308,17 @@ class ParentSingleton : public nsISupports return NS_OK; } + void + SetProfileDir(nsIFile* aProfileDir) + { + MOZ_ASSERT(!NS_IsMainThread()); + bool first = !mProfileDir; + mProfileDir = aProfileDir; + // Load from disk when we first get a profileDir, but not subsequently. + if (first) { + Load(); + } + } private: nsCOMPtr mProfileDir; }; @@ -355,25 +357,60 @@ Parent::RecvGetOriginKey(const uint32_t& aRequestId, const nsCString& aOrigin, const bool& aPrivateBrowsing) { - // Hand over to stream-transport thread. + // TODO: Replace all this when moving MediaParent to PContent soon (1037389) - nsCOMPtr sts = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID); - MOZ_ASSERT(sts); nsRefPtr singleton(mSingleton); + nsCOMPtr returnThread = NS_GetCurrentThread(); + nsRefPtr> p = new Pledge(); + nsresult rv; - nsRefPtr> p = PledgeRunnable::New( - [singleton, aOrigin, aPrivateBrowsing](nsCString& aResult) { - if (aPrivateBrowsing) { - singleton->mPrivateBrowsingOriginKeys.GetOriginKey(aOrigin, aResult); - } else { - singleton->mOriginKeys.GetOriginKey(aOrigin, aResult); + // First, over to main thread to get profile dir. + + rv = NS_DispatchToMainThread(NewRunnableFrom([p, returnThread, singleton, aOrigin, + aPrivateBrowsing]() -> nsresult { + MOZ_ASSERT(NS_IsMainThread()); + nsCOMPtr profileDir; + nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, + getter_AddRefs(profileDir)); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + // Then from there over to stream-transport thread to do the actual file io. + + nsCOMPtr sts = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID); + MOZ_ASSERT(sts); + rv = sts->Dispatch(NewRunnableFrom([profileDir, p, returnThread, singleton, + aOrigin, aPrivateBrowsing]() -> nsresult { + MOZ_ASSERT(!NS_IsMainThread()); + singleton->mOriginKeys.SetProfileDir(profileDir); + nsCString result; + if (aPrivateBrowsing) { + singleton->mPrivateBrowsingOriginKeys.GetOriginKey(aOrigin, result); + } else { + singleton->mOriginKeys.GetOriginKey(aOrigin, result); + } + + // Pass result back to original thread. + nsresult rv; + rv = returnThread->Dispatch(NewRunnableFrom([p, result]() -> nsresult { + p->Resolve(result); + return NS_OK; + }), NS_DISPATCH_NORMAL); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + return NS_OK; + }), NS_DISPATCH_NORMAL); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; } return NS_OK; - }); - nsresult rv = sts->Dispatch(p, NS_DISPATCH_NORMAL); + })); if (NS_WARN_IF(NS_FAILED(rv))) { return false; } + nsRefPtr keepAlive(this); p->Then([this, keepAlive, aRequestId](const nsCString& aKey) mutable { if (!mDestroyed) { @@ -387,19 +424,36 @@ Parent::RecvGetOriginKey(const uint32_t& aRequestId, bool Parent::RecvSanitizeOriginKeys(const uint64_t& aSinceWhen) { - // Hand over to stream-transport thread. - - nsCOMPtr sts = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID); - MOZ_ASSERT(sts); nsRefPtr singleton(mSingleton); - nsRefPtr> p = PledgeRunnable::New( - [singleton, aSinceWhen](bool) { - singleton->mPrivateBrowsingOriginKeys.Clear(aSinceWhen); - singleton->mOriginKeys.Clear(aSinceWhen); + // First, over to main to get profile dir. + nsresult rv; + + rv = NS_DispatchToMainThread(NewRunnableFrom([singleton, + aSinceWhen]() -> nsresult { + MOZ_ASSERT(NS_IsMainThread()); + nsCOMPtr profileDir; + nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, + getter_AddRefs(profileDir)); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + // Then from there over to stream-transport thread to do the file io. + + nsCOMPtr sts = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID); + MOZ_ASSERT(sts); + rv = sts->Dispatch(NewRunnableFrom([profileDir, singleton, aSinceWhen]() -> nsresult { + MOZ_ASSERT(!NS_IsMainThread()); + singleton->mOriginKeys.SetProfileDir(profileDir); + singleton->mPrivateBrowsingOriginKeys.Clear(aSinceWhen); + singleton->mOriginKeys.Clear(aSinceWhen); + return NS_OK; + }), NS_DISPATCH_NORMAL); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } return NS_OK; - }); - nsresult rv = sts->Dispatch(p, NS_DISPATCH_NORMAL); + })); if (NS_WARN_IF(NS_FAILED(rv))) { return false; } diff --git a/dom/media/systemservices/MediaUtils.h b/dom/media/systemservices/MediaUtils.h index 85546f8c8d9..03b3bf039a8 100644 --- a/dom/media/systemservices/MediaUtils.h +++ b/dom/media/systemservices/MediaUtils.h @@ -37,6 +37,7 @@ class Pledge }; public: + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(Pledge); explicit Pledge() : mDone(false), mResult(NS_OK) {} template @@ -77,13 +78,12 @@ public: } } -protected: void Resolve(const ValueType& aValue) { mValue = aValue; Resolve(); } - +protected: void Resolve() { if (!mDone) { @@ -108,63 +108,13 @@ protected: ValueType mValue; protected: + ~Pledge() {}; bool mDone; nsresult mResult; private: nsAutoPtr mFunctors; }; -// General purpose runnable that also acts as a Pledge for the resulting value. -// Use PledgeRunnable<>::New() factory function to use with lambdas. - -template -class PledgeRunnable : public Pledge, public nsRunnable -{ -public: - template - static PledgeRunnable* - New(OnRunType aOnRun) - { - class P : public PledgeRunnable - { - public: - explicit P(OnRunType& aOnRun) - : mOriginThread(NS_GetCurrentThread()) - , mOnRun(aOnRun) - , mHasRun(false) {} - private: - virtual ~P() {} - NS_IMETHODIMP - Run() - { - if (!mHasRun) { - P::mResult = mOnRun(P::mValue); - mHasRun = true; - return mOriginThread->Dispatch(this, NS_DISPATCH_NORMAL); - } - bool on; - MOZ_RELEASE_ASSERT(NS_SUCCEEDED(mOriginThread->IsOnCurrentThread(&on))); - MOZ_RELEASE_ASSERT(on); - - if (NS_SUCCEEDED(P::mResult)) { - P::Resolve(); - } else { - P::Reject(P::mResult); - } - return NS_OK; - } - nsCOMPtr mOriginThread; - OnRunType mOnRun; - bool mHasRun; - }; - - return new P(aOnRun); - } - -protected: - virtual ~PledgeRunnable() {} -}; - // General purpose runnable with an eye toward lambdas template