Bug 1584339 - move background event target logic into a separate class; r=KrisWright

Eventually, we're going to want to hand out an `nsIEventTarget*` to people
wanting to dispatch to background threads, but for whatever reason not
wanting to use the `NS_DispatchToBackgroundThread` API (probably because
they want to verify correctness by checking that certain methods are, in
fact, running on the background event target).  And because we're going to
want to have some sort of division between CPU-bound and IO-bound tasks, we
can't just hand out references to a single thread pool.  We need some sort
of intermediate object for both of these goals, and that is what the added
`BackgroundEventTarget` class is.

Differential Revision: https://phabricator.services.mozilla.com/D47343

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Nathan Froyd 2019-09-27 15:30:34 +00:00
Родитель e09d436481
Коммит 580e41da6a
2 изменённых файлов: 82 добавлений и 20 удалений

Просмотреть файл

@ -37,6 +37,82 @@ static MOZ_THREAD_LOCAL(PRThread*) gTlsCurrentVirtualThread;
bool NS_IsMainThreadTLSInitialized() { return sTLSIsMainThread.initialized(); }
class BackgroundEventTarget final : public nsIEventTarget
{
public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIEVENTTARGET_FULL
BackgroundEventTarget() = default;
nsresult Init();
nsresult Shutdown();
private:
~BackgroundEventTarget() = default;
nsCOMPtr<nsIThreadPool> mPool;
};
NS_IMPL_ISUPPORTS(BackgroundEventTarget, nsIEventTarget)
nsresult BackgroundEventTarget::Init() {
nsCOMPtr<nsIThreadPool> pool(new nsThreadPool());
NS_ENSURE_TRUE(pool, NS_ERROR_FAILURE);
nsresult rv = pool->SetName(NS_LITERAL_CSTRING("BackgroundThreadPool"));
NS_ENSURE_SUCCESS(rv, rv);
// Use potentially more conservative stack size.
rv = pool->SetThreadStackSize(nsIThreadManager::kThreadPoolStackSize);
NS_ENSURE_SUCCESS(rv, rv);
// For now just one thread. Can increase easily later if we want.
rv = pool->SetThreadLimit(1);
NS_ENSURE_SUCCESS(rv, rv);
// Leave threads alive for up to 5 minutes
rv = pool->SetIdleThreadTimeout(300000);
NS_ENSURE_SUCCESS(rv, rv);
pool.swap(mPool);
return NS_OK;
}
NS_IMETHODIMP_(bool)
BackgroundEventTarget::IsOnCurrentThreadInfallible() {
return mPool->IsOnCurrentThread();
}
NS_IMETHODIMP
BackgroundEventTarget::IsOnCurrentThread(bool* aValue) {
return mPool->IsOnCurrentThread(aValue);
}
NS_IMETHODIMP
BackgroundEventTarget::Dispatch(already_AddRefed<nsIRunnable> aRunnable,
uint32_t aFlags) {
return mPool->Dispatch(std::move(aRunnable), aFlags);
}
NS_IMETHODIMP
BackgroundEventTarget::DispatchFromScript(nsIRunnable* aRunnable, uint32_t aFlags) {
return mPool->Dispatch(aRunnable, aFlags);
}
NS_IMETHODIMP
BackgroundEventTarget::DelayedDispatch(already_AddRefed<nsIRunnable> aRunnable, uint32_t) {
nsCOMPtr<nsIRunnable> dropRunnable(aRunnable);
return NS_ERROR_NOT_IMPLEMENTED;
}
nsresult
BackgroundEventTarget::Shutdown() {
return mPool->Shutdown();
}
extern "C" {
// This uses the C language linkage because it's exposed to Rust
// via the xpcom/rust/moz_task crate.
@ -247,25 +323,12 @@ nsresult nsThreadManager::Init() {
AbstractThread::InitMainThread();
// Initialize the background event target.
nsCOMPtr<nsIThreadPool> pool(new nsThreadPool());
NS_ENSURE_TRUE(pool, NS_ERROR_FAILURE);
RefPtr<BackgroundEventTarget> target(new BackgroundEventTarget());
rv = pool->SetName(NS_LITERAL_CSTRING("BackgroundThreadPool"));
rv = target->Init();
NS_ENSURE_SUCCESS(rv, rv);
// Use potentially more conservative stack size.
rv = pool->SetThreadStackSize(nsIThreadManager::kThreadPoolStackSize);
NS_ENSURE_SUCCESS(rv, rv);
// For now just one thread. Can increase easily later if we want.
rv = pool->SetThreadLimit(1);
NS_ENSURE_SUCCESS(rv, rv);
// Leave threads alive for up to 5 minutes
rv = pool->SetIdleThreadTimeout(300000);
NS_ENSURE_SUCCESS(rv, rv);
pool.swap(mBackgroundEventTarget);
mBackgroundEventTarget = target.forget();
mInitialized = true;
@ -287,7 +350,7 @@ void nsThreadManager::Shutdown() {
// Empty the main thread event queue before we begin shutting down threads.
NS_ProcessPendingEvents(mMainThread);
mBackgroundEventTarget->Shutdown();
static_cast<BackgroundEventTarget*>(mBackgroundEventTarget.get())->Shutdown();
{
// We gather the threads from the hashtable into a list, so that we avoid
@ -395,7 +458,7 @@ nsresult nsThreadManager::DispatchToBackgroundThread(nsIRunnable* aEvent,
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIThreadPool> backgroundTarget(mBackgroundEventTarget);
nsCOMPtr<nsIEventTarget> backgroundTarget(mBackgroundEventTarget);
return backgroundTarget->Dispatch(aEvent, aDispatchFlags);
}

Просмотреть файл

@ -9,7 +9,6 @@
#include "mozilla/Mutex.h"
#include "nsIThreadManager.h"
#include "nsIThreadPool.h"
#include "nsThread.h"
class nsIRunnable;
@ -88,7 +87,7 @@ class nsThreadManager : public nsIThreadManager {
mInitialized;
// Shared event target used for background runnables.
nsCOMPtr<nsIThreadPool> mBackgroundEventTarget;
nsCOMPtr<nsIEventTarget> mBackgroundEventTarget;
};
#define NS_THREADMANAGER_CID \