Bug 1345251 Make MozPromise usable on worker threads. r=gerald

This commit is contained in:
Ben Kelly 2017-03-08 11:45:07 -05:00
parent 209b6df381
commit 7300a549b0
3 changed files with 67 additions and 21 deletions

View File

@ -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);

View File

@ -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.

View File

@ -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;