зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
e09d436481
Коммит
580e41da6a
|
@ -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 \
|
||||
|
|
Загрузка…
Ссылка в новой задаче