mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 02:14:43 +00:00
Bug 1345251 Make MozPromise usable on worker threads. r=gerald
This commit is contained in:
parent
209b6df381
commit
7300a549b0
@ -26,6 +26,7 @@
|
||||
#include "BackgroundChild.h"
|
||||
#include "GeckoProfiler.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "mozilla/AbstractThread.h"
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/AsyncEventDispatcher.h"
|
||||
#include "mozilla/Atomics.h"
|
||||
@ -2816,10 +2817,12 @@ WorkerThreadPrimaryRunnable::Run()
|
||||
{
|
||||
// Raw pointer: this class is on the stack.
|
||||
WorkerPrivate* mWorkerPrivate;
|
||||
RefPtr<AbstractThread> mAbstractThread;
|
||||
|
||||
public:
|
||||
SetThreadHelper(WorkerPrivate* aWorkerPrivate, WorkerThread* aThread)
|
||||
: mWorkerPrivate(aWorkerPrivate)
|
||||
, mAbstractThread(AbstractThread::CreateXPCOMThreadWrapper(NS_GetCurrentThread(), false))
|
||||
{
|
||||
MOZ_ASSERT(aWorkerPrivate);
|
||||
MOZ_ASSERT(aThread);
|
||||
|
@ -128,7 +128,25 @@ private:
|
||||
return runner.forget();
|
||||
}
|
||||
|
||||
class Runner : public Runnable {
|
||||
class Runner : public CancelableRunnable {
|
||||
class MOZ_STACK_CLASS AutoTaskGuard final {
|
||||
public:
|
||||
explicit AutoTaskGuard(EventTargetWrapper* aThread)
|
||||
: mLastCurrentThread(nullptr)
|
||||
{
|
||||
MOZ_ASSERT(aThread);
|
||||
mLastCurrentThread = sCurrentThreadTLS.get();
|
||||
sCurrentThreadTLS.set(aThread);
|
||||
}
|
||||
|
||||
~AutoTaskGuard()
|
||||
{
|
||||
sCurrentThreadTLS.set(mLastCurrentThread);
|
||||
}
|
||||
private:
|
||||
AbstractThread* mLastCurrentThread;
|
||||
};
|
||||
|
||||
public:
|
||||
explicit Runner(EventTargetWrapper* aThread,
|
||||
already_AddRefed<nsIRunnable> aRunnable,
|
||||
@ -141,23 +159,7 @@ private:
|
||||
|
||||
NS_IMETHOD Run() override
|
||||
{
|
||||
class MOZ_STACK_CLASS AutoTaskGuard final {
|
||||
public:
|
||||
explicit AutoTaskGuard(EventTargetWrapper* aThread)
|
||||
: mLastCurrentThread(nullptr)
|
||||
{
|
||||
MOZ_ASSERT(aThread);
|
||||
mLastCurrentThread = sCurrentThreadTLS.get();
|
||||
sCurrentThreadTLS.set(aThread);
|
||||
}
|
||||
|
||||
~AutoTaskGuard()
|
||||
{
|
||||
sCurrentThreadTLS.set(mLastCurrentThread);
|
||||
}
|
||||
private:
|
||||
AbstractThread* mLastCurrentThread;
|
||||
} taskGuard(mThread);
|
||||
AutoTaskGuard taskGuard(mThread);
|
||||
|
||||
MOZ_ASSERT(mThread == AbstractThread::GetCurrent());
|
||||
MOZ_ASSERT(mThread->IsCurrentThreadIn());
|
||||
@ -170,6 +172,23 @@ private:
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult Cancel() override
|
||||
{
|
||||
// Set the TLS during Cancel() just in case it calls Run().
|
||||
AutoTaskGuard taskGuard(mThread);
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
// Try to cancel the runnable if it implements the right interface.
|
||||
// Otherwise just skip the runnable.
|
||||
nsCOMPtr<nsICancelableRunnable> cr = do_QueryInterface(mRunnable);
|
||||
if (cr) {
|
||||
rv = cr->Cancel();
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHOD GetName(nsACString& aName) override
|
||||
{
|
||||
aName.AssignLiteral("AbstractThread::Runner");
|
||||
@ -265,6 +284,15 @@ already_AddRefed<AbstractThread>
|
||||
AbstractThread::CreateXPCOMThreadWrapper(nsIThread* aThread, bool aRequireTailDispatch)
|
||||
{
|
||||
RefPtr<EventTargetWrapper> wrapper = new EventTargetWrapper(aThread, aRequireTailDispatch);
|
||||
|
||||
bool onCurrentThread = false;
|
||||
Unused << aThread->IsOnCurrentThread(&onCurrentThread);
|
||||
|
||||
if (onCurrentThread) {
|
||||
sCurrentThreadTLS.set(wrapper);
|
||||
return wrapper.forget();
|
||||
}
|
||||
|
||||
// Set the thread-local sCurrentThreadTLS to point to the wrapper on the
|
||||
// target thread. This ensures that sCurrentThreadTLS is as expected by
|
||||
// AbstractThread::GetCurrent() on the target thread.
|
||||
|
@ -316,7 +316,7 @@ protected:
|
||||
static const uint32_t sMagic = 0xfadece11;
|
||||
|
||||
public:
|
||||
class ResolveOrRejectRunnable : public Runnable
|
||||
class ResolveOrRejectRunnable : public CancelableRunnable
|
||||
{
|
||||
public:
|
||||
ResolveOrRejectRunnable(ThenValueBase* aThenValue, MozPromise* aPromise)
|
||||
@ -342,6 +342,11 @@ protected:
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult Cancel() override
|
||||
{
|
||||
return Run();
|
||||
}
|
||||
|
||||
private:
|
||||
RefPtr<ThenValueBase> mThenValue;
|
||||
RefPtr<MozPromise> mPromise;
|
||||
@ -1218,7 +1223,7 @@ private:
|
||||
|
||||
template<typename PromiseType, typename MethodType, typename ThisType,
|
||||
typename... Storages>
|
||||
class ProxyRunnable : public Runnable
|
||||
class ProxyRunnable : public CancelableRunnable
|
||||
{
|
||||
public:
|
||||
ProxyRunnable(typename PromiseType::Private* aProxyPromise,
|
||||
@ -1233,6 +1238,11 @@ public:
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult Cancel() override
|
||||
{
|
||||
return Run();
|
||||
}
|
||||
|
||||
private:
|
||||
RefPtr<typename PromiseType::Private> mProxyPromise;
|
||||
nsAutoPtr<MethodCall<PromiseType, MethodType, ThisType, Storages...>> mMethodCall;
|
||||
@ -1324,7 +1334,7 @@ InvokeAsync(AbstractThread* aTarget, ThisType* aThisVal, const char* aCallerName
|
||||
namespace detail {
|
||||
|
||||
template<typename Function, typename PromiseType>
|
||||
class ProxyFunctionRunnable : public Runnable
|
||||
class ProxyFunctionRunnable : public CancelableRunnable
|
||||
{
|
||||
typedef typename Decay<Function>::Type FunctionStorage;
|
||||
public:
|
||||
@ -1342,6 +1352,11 @@ public:
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult Cancel() override
|
||||
{
|
||||
return Run();
|
||||
}
|
||||
|
||||
private:
|
||||
RefPtr<typename PromiseType::Private> mProxyPromise;
|
||||
UniquePtr<FunctionStorage> mFunction;
|
||||
|
Loading…
Reference in New Issue
Block a user