Bug 1366072 - Expose an event target for MessageLoop (r=kanru)

MozReview-Commit-ID: 8vWOGO2zzPs
This commit is contained in:
Bill McCloskey 2017-06-09 13:32:48 -07:00
parent bbed3cf3c1
commit eee9dad55a
2 changed files with 95 additions and 1 deletions

View File

@ -29,6 +29,7 @@
#ifdef ANDROID
#include "base/message_pump_android.h"
#endif
#include "nsISerialEventTarget.h"
#ifdef MOZ_TASK_TRACER
#include "GeckoTaskTracer.h"
#include "TracedTaskCommon.h"
@ -84,6 +85,84 @@ static LPTOP_LEVEL_EXCEPTION_FILTER GetTopSEHFilter() {
//------------------------------------------------------------------------------
class MessageLoop::EventTarget
: public nsISerialEventTarget
, public MessageLoop::DestructionObserver
{
public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIEVENTTARGET_FULL
explicit EventTarget(MessageLoop* aLoop) : mLoop(aLoop) {
aLoop->AddDestructionObserver(this);
}
private:
virtual ~EventTarget() {
if (mLoop) {
mLoop->RemoveDestructionObserver(this);
}
}
void WillDestroyCurrentMessageLoop() override {
mLoop->RemoveDestructionObserver(this);
mLoop = nullptr;
}
MessageLoop* mLoop;
};
NS_IMPL_ISUPPORTS(MessageLoop::EventTarget, nsIEventTarget, nsISerialEventTarget)
NS_IMETHODIMP_(bool)
MessageLoop::EventTarget::IsOnCurrentThreadInfallible()
{
return mLoop == MessageLoop::current();
}
NS_IMETHODIMP
MessageLoop::EventTarget::IsOnCurrentThread(bool* aResult)
{
*aResult = IsOnCurrentThreadInfallible();
return NS_OK;
}
NS_IMETHODIMP
MessageLoop::EventTarget::DispatchFromScript(nsIRunnable* aEvent, uint32_t aFlags)
{
nsCOMPtr<nsIRunnable> event(aEvent);
return Dispatch(event.forget(), aFlags);
}
NS_IMETHODIMP
MessageLoop::EventTarget::Dispatch(already_AddRefed<nsIRunnable> aEvent, uint32_t aFlags)
{
if (!mLoop) {
return NS_ERROR_NOT_INITIALIZED;
}
if (aFlags != NS_DISPATCH_NORMAL) {
return NS_ERROR_NOT_IMPLEMENTED;
}
mLoop->PostTask(Move(aEvent));
return NS_OK;
}
NS_IMETHODIMP
MessageLoop::EventTarget::DelayedDispatch(already_AddRefed<nsIRunnable> aEvent,
uint32_t aDelayMs)
{
if (!mLoop) {
return NS_ERROR_NOT_INITIALIZED;
}
mLoop->PostDelayedTask(Move(aEvent), aDelayMs);
return NS_OK;
}
//------------------------------------------------------------------------------
// static
MessageLoop* MessageLoop::current() {
return get_tls_ptr().Get();
@ -103,7 +182,8 @@ MessageLoop::MessageLoop(Type type, nsIThread* aThread)
#endif // OS_WIN
transient_hang_timeout_(0),
permanent_hang_timeout_(0),
next_sequence_num_(0) {
next_sequence_num_(0),
mEventTarget(new EventTarget(this)) {
DCHECK(!current()) << "should only have one message loop per thread";
get_tls_ptr().Set(this);
@ -524,6 +604,13 @@ bool MessageLoop::PendingTask::operator<(const PendingTask& other) const {
return (sequence_num - other.sequence_num) > 0;
}
//------------------------------------------------------------------------------
// MessageLoop::SerialEventTarget
nsISerialEventTarget* MessageLoop::SerialEventTarget() {
return mEventTarget;
}
//------------------------------------------------------------------------------
// MessageLoopForUI

View File

@ -30,6 +30,7 @@
#include "nsIRunnable.h"
#include "nsThreadUtils.h"
class nsISerialEventTarget;
class nsIThread;
namespace mozilla {
@ -145,6 +146,9 @@ public:
}
};
// Return an XPCOM-compatible event target for this thread.
nsISerialEventTarget* SerialEventTarget();
// A MessageLoop has a particular type, which indicates the set of
// asynchronous events it may process in addition to tasks and timers.
//
@ -438,6 +442,9 @@ public:
// The next sequence number to use for delayed tasks.
int next_sequence_num_;
class EventTarget;
RefPtr<EventTarget> mEventTarget;
DISALLOW_COPY_AND_ASSIGN(MessageLoop);
};