Bug 1368072 - Move idle dispatch to thread manager. r=froydnj

Also exposes idle dispatch with timeout.
This commit is contained in:
Andreas Farre 2017-06-19 06:36:00 +02:00
Родитель 0db11efe83
Коммит 9598aa65ed
7 изменённых файлов: 96 добавлений и 45 удалений

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

@ -512,12 +512,6 @@ LazyIdleThread::IdleDispatch(already_AddRefed<nsIRunnable> aEvent)
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
LazyIdleThread::IdleDispatchFromScript(nsIRunnable* aEvent)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
LazyIdleThread::RegisterIdlePeriod(already_AddRefed<nsIIdlePeriod> aIdlePeriod)
{

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

@ -150,22 +150,7 @@ interface nsIThread : nsISerialEventTarget
* Indicates that the thread is shutting down and has finished processing
* events, so this event would never run and has not been dispatched.
*/
[noscript, binaryname(IdleDispatch)] void idleDispatchFromC(in alreadyAddRefed_nsIRunnable event);
/**
* Dispatch an event to the thread's idle queue. This function may be called
* from any thread, and it may be called re-entrantly.
*
* @param event
* The (raw) event to dispatch.
*
* @throws NS_ERROR_INVALID_ARG
* Indicates that event is null.
* @throws NS_ERROR_UNEXPECTED
* Indicates that the thread is shutting down and has finished processing
* events, so this event would never run and has not been dispatched.
*/
[binaryname(IdleDispatchFromScript)] void idleDispatch(in nsIRunnable event);
[noscript] void idleDispatch(in alreadyAddRefed_nsIRunnable event);
/**
* Use this attribute to dispatch runnables to the thread. Eventually, the

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

@ -90,4 +90,18 @@ interface nsIThreadManager : nsISupports
* C++ callers should instead use NS_DispatchToMainThread.
*/
void dispatchToMainThread(in nsIRunnable event);
/**
* This queues a runnable to the main thread's idle queue.
*
* @param event
* The event to dispatch.
* @param timeout
* The time in milliseconds until this event should be moved from the idle
* queue to the regular queue if it hasn't been executed by then. If not
* passed or a zero value is specified, the event will never be moved to
* the regular queue.
*/
void idleDispatchToMainThread(in nsIRunnable event,
[optional] in uint32_t timeout);
};

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

@ -1162,13 +1162,6 @@ nsThread::IdleDispatch(already_AddRefed<nsIRunnable> aEvent)
return NS_OK;
}
NS_IMETHODIMP
nsThread::IdleDispatchFromScript(nsIRunnable* aEvent)
{
nsCOMPtr<nsIRunnable> event(aEvent);
return IdleDispatch(event.forget());
}
#ifdef MOZ_CANARY
void canary_alarm_handler(int signum);

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

@ -263,7 +263,7 @@ nsThreadManager::NewNamedThread(const nsACString& aName,
nsIThread** aResult)
{
// Note: can be called from arbitrary threads
// No new threads during Shutdown
if (NS_WARN_IF(!mInitialized)) {
return NS_ERROR_NOT_INITIALIZED;
@ -367,3 +367,18 @@ nsThreadManager::DispatchToMainThread(nsIRunnable *aEvent)
return mMainThread->DispatchFromScript(aEvent, 0);
}
NS_IMETHODIMP
nsThreadManager::IdleDispatchToMainThread(nsIRunnable *aEvent, uint32_t aTimeout)
{
// Note: C++ callers should instead use NS_IdleDispatchToThread or
// NS_IdleDispatchToCurrentThread.
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsIRunnable> event(aEvent);
if (aTimeout) {
return NS_IdleDispatchToThread(event.forget(), aTimeout, mMainThread);
}
return NS_IdleDispatchToThread(event.forget(), mMainThread);
}

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

@ -279,27 +279,19 @@ NS_DelayedDispatchToCurrentThread(already_AddRefed<nsIRunnable>&& aEvent, uint32
}
nsresult
NS_IdleDispatchToCurrentThread(already_AddRefed<nsIRunnable>&& aEvent)
NS_IdleDispatchToThread(already_AddRefed<nsIRunnable>&& aEvent,
nsIThread* aThread)
{
nsresult rv;
nsCOMPtr<nsIRunnable> event(aEvent);
NS_ENSURE_TRUE(event, NS_ERROR_INVALID_ARG);
#ifdef MOZILLA_INTERNAL_API
nsIThread* thread = NS_GetCurrentThread();
if (!thread) {
if (!aThread) {
return NS_ERROR_UNEXPECTED;
}
#else
nsCOMPtr<nsIThread> thread;
rv = NS_GetCurrentThread(getter_AddRefs(thread));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
#endif
// To keep us from leaking the runnable if dispatch method fails,
// we grab the reference on failures and release it.
nsIRunnable* temp = event.get();
rv = thread->IdleDispatch(event.forget());
rv = aThread->IdleDispatch(event.forget());
if (NS_WARN_IF(NS_FAILED(rv))) {
// Dispatch() leaked the reference to the event, but due to caller's
// assumptions, we shouldn't leak here. And given we are on the same
@ -310,6 +302,13 @@ NS_IdleDispatchToCurrentThread(already_AddRefed<nsIRunnable>&& aEvent)
return rv;
}
nsresult
NS_IdleDispatchToCurrentThread(already_AddRefed<nsIRunnable>&& aEvent)
{
return NS_IdleDispatchToThread(Move(aEvent),
NS_GetCurrentThread());
}
class IdleRunnableWrapper : public IdleRunnable
{
public:
@ -365,8 +364,9 @@ private:
};
extern nsresult
NS_IdleDispatchToCurrentThread(already_AddRefed<nsIRunnable>&& aEvent,
uint32_t aTimeout)
NS_IdleDispatchToThread(already_AddRefed<nsIRunnable>&& aEvent,
uint32_t aTimeout,
nsIThread* aThread)
{
nsCOMPtr<nsIRunnable> event(Move(aEvent));
NS_ENSURE_TRUE(event, NS_ERROR_INVALID_ARG);
@ -384,7 +384,15 @@ NS_IdleDispatchToCurrentThread(already_AddRefed<nsIRunnable>&& aEvent,
}
idleEvent->SetTimer(aTimeout, target);
return NS_IdleDispatchToCurrentThread(event.forget());
return NS_IdleDispatchToThread(event.forget(), aThread);
}
extern nsresult
NS_IdleDispatchToCurrentThread(already_AddRefed<nsIRunnable>&& aEvent,
uint32_t aTimeout)
{
return NS_IdleDispatchToThread(Move(aEvent), aTimeout,
NS_GetCurrentThread());
}
#ifndef XPCOM_GLUE_AVOID_NSPR

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

@ -152,6 +152,48 @@ NS_IdleDispatchToCurrentThread(already_AddRefed<nsIRunnable>&& aEvent);
extern nsresult
NS_IdleDispatchToCurrentThread(already_AddRefed<nsIRunnable>&& aEvent, uint32_t aTimeout);
/**
* Dispatch the given event to the idle queue of a thread.
*
* @param aEvent The event to dispatch.
*
* @param aThread The target thread for the dispatch.
*
* @returns NS_ERROR_INVALID_ARG
* If event is null.
* @returns NS_ERROR_UNEXPECTED
* If the thread is shutting down.
*/
extern nsresult
NS_IdleDispatchToThread(already_AddRefed<nsIRunnable>&& aEvent,
nsIThread* aThread);
/**
* Dispatch the given event to the idle queue of a thread.
*
* @param aEvent The event to dispatch. If the event implements
* nsIIdleRunnable, it will receive a call on
* nsIIdleRunnable::SetTimer when dispatched, with the value of
* aTimeout.
*
* @param aTimeout The time in milliseconds until the event should be
* moved from the idle queue to the regular queue, if it hasn't been
* executed. If aEvent is also an nsIIdleRunnable, it is expected
* that it should handle the timeout itself, after a call to
* nsIIdleRunnable::SetTimer.
*
* @param aThread The target thread for the dispatch.
*
* @returns NS_ERROR_INVALID_ARG
* If event is null.
* @returns NS_ERROR_UNEXPECTED
* If the thread is shutting down.
*/
extern nsresult
NS_IdleDispatchToThread(already_AddRefed<nsIRunnable>&& aEvent,
uint32_t aTimeout,
nsIThread* aThread);
#ifndef XPCOM_GLUE_AVOID_NSPR
/**
* Process all pending events for the given thread before returning. This