Bug 1529581 - Introduce initHighResolutionWithNamedFuncCallback for nsITimer. r=xpcom-reviewers,nika

Differential Revision: https://phabricator.services.mozilla.com/D129654
This commit is contained in:
Andreas Pehrson 2021-11-02 14:35:58 +00:00
Родитель 925be8237f
Коммит b9f92d2e95
4 изменённых файлов: 96 добавлений и 12 удалений

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

@ -19,6 +19,7 @@
#include "mozilla/Monitor.h"
#include "mozilla/ReentrantMonitor.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "mozilla/StaticPrefs_timer.h"
#include <list>
@ -890,3 +891,33 @@ TEST(Timers, ClosureCallback)
}
ASSERT_EQ(notifiedThread, testThread);
}
static void SetTime(nsITimer* aTimer, void* aClosure) {
*static_cast<TimeStamp*>(aClosure) = TimeStamp::Now();
}
TEST(Timers, HighResFuncCallback)
{
TimeStamp first;
TimeStamp second;
TimeStamp third;
nsCOMPtr<nsITimer> t1 = NS_NewTimer(GetCurrentSerialEventTarget());
nsCOMPtr<nsITimer> t2 = NS_NewTimer(GetCurrentSerialEventTarget());
nsCOMPtr<nsITimer> t3 = NS_NewTimer(GetCurrentSerialEventTarget());
// Reverse order, since if the timers are not high-res we'd end up
// out-of-order.
MOZ_ALWAYS_SUCCEEDS(t3->InitHighResolutionWithNamedFuncCallback(
&SetTime, &third, TimeDuration::FromMicroseconds(300),
nsITimer::TYPE_ONE_SHOT, "TestTimers::HighResFuncCallback::third"));
MOZ_ALWAYS_SUCCEEDS(t2->InitHighResolutionWithNamedFuncCallback(
&SetTime, &second, TimeDuration::FromMicroseconds(200),
nsITimer::TYPE_ONE_SHOT, "TestTimers::HighResFuncCallback::second"));
MOZ_ALWAYS_SUCCEEDS(t1->InitHighResolutionWithNamedFuncCallback(
&SetTime, &first, TimeDuration::FromMicroseconds(100),
nsITimer::TYPE_ONE_SHOT, "TestTimers::HighResFuncCallback::first"));
SpinEventLoopUntil<ProcessFailureBehavior::IgnoreAndContinue>(
"TestTimers::HighResFuncCallback"_ns,
[&] { return !first.IsNull() && !second.IsNull() && !third.IsNull(); });
}

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

@ -158,7 +158,7 @@ interface nsITimer : nsISupports
* @param aDelay The high resolution interval
* @param aType Timer type per TYPE* consts defined above
*/
[noscript] void InitHighResolutionWithCallback(in nsITimerCallback aCallback,
[noscript] void initHighResolutionWithCallback(in nsITimerCallback aCallback,
[const] in TimeDuration aDelay,
in unsigned long aType);
@ -187,6 +187,23 @@ interface nsITimer : nsISupports
in unsigned long aType,
in string aName);
/**
* Initialize a timer to fire after the high resolution TimeDuration.
* This version takes a named function callback.
*
* @param aFunc The function to invoke
* @param aClosure An opaque pointer to pass to that function
* @param aDelay The high resolution interval
* @param aType Timer type per TYPE* consts defined above
* @param aName The timer's name
*/
[noscript] void initHighResolutionWithNamedFuncCallback(
in nsTimerCallbackFunc aCallback,
in voidPtr aClosure,
[const] in TimeDuration aDelay,
in unsigned long aType,
in string aName);
/**
* The millisecond delay of the timeout.
*
@ -317,6 +334,22 @@ NS_NewTimerWithFuncCallback(nsTimerCallbackFunc aCallback,
const char* aNameString,
nsIEventTarget* aTarget = nullptr);
nsresult
NS_NewTimerWithFuncCallback(nsITimer** aTimer,
nsTimerCallbackFunc aCallback,
void* aClosure,
const mozilla::TimeDuration& aDelay,
uint32_t aType,
const char* aNameString,
nsIEventTarget* aTarget = nullptr);
mozilla::Result<nsCOMPtr<nsITimer>, nsresult>
NS_NewTimerWithFuncCallback(nsTimerCallbackFunc aCallback,
void* aClosure,
const mozilla::TimeDuration& aDelay,
uint32_t aType,
const char* aNameString,
nsIEventTarget* aTarget = nullptr);
#define NS_TIMER_CONTRACTID "@mozilla.org/timer;1"
#define NS_TIMER_CALLBACK_TOPIC "timer-callback"

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

@ -262,6 +262,28 @@ nsresult NS_NewTimerWithFuncCallback(nsITimer** aTimer,
return NS_OK;
}
mozilla::Result<nsCOMPtr<nsITimer>, nsresult> NS_NewTimerWithFuncCallback(
nsTimerCallbackFunc aCallback, void* aClosure, const TimeDuration& aDelay,
uint32_t aType, const char* aNameString, nsIEventTarget* aTarget) {
nsCOMPtr<nsITimer> timer;
MOZ_TRY(NS_NewTimerWithFuncCallback(getter_AddRefs(timer), aCallback,
aClosure, aDelay, aType, aNameString,
aTarget));
return std::move(timer);
}
nsresult NS_NewTimerWithFuncCallback(nsITimer** aTimer,
nsTimerCallbackFunc aCallback,
void* aClosure, const TimeDuration& aDelay,
uint32_t aType, const char* aNameString,
nsIEventTarget* aTarget) {
auto timer = nsTimer::WithEventTarget(aTarget);
MOZ_TRY(timer->InitHighResolutionWithNamedFuncCallback(
aCallback, aClosure, aDelay, aType, aNameString));
timer.forget(aTimer);
return NS_OK;
}
// This module prints info about which timers are firing, which is useful for
// wakeups for the purposes of power profiling. Set the following environment
// variable before starting the browser.
@ -366,13 +388,6 @@ void nsTimerImpl::Shutdown() {
gThreadWrapper.Shutdown();
}
nsresult nsTimerImpl::InitCommon(uint32_t aDelayMS, uint32_t aType,
Callback&& aNewCallback,
const MutexAutoLock& aProofOfLock) {
return InitCommon(TimeDuration::FromMilliseconds(aDelayMS), aType,
std::move(aNewCallback), aProofOfLock);
}
nsresult nsTimerImpl::InitCommon(const TimeDuration& aDelay, uint32_t aType,
Callback&& newCallback,
const MutexAutoLock& aProofOfLock) {
@ -399,6 +414,13 @@ nsresult nsTimerImpl::InitWithNamedFuncCallback(nsTimerCallbackFunc aFunc,
void* aClosure, uint32_t aDelay,
uint32_t aType,
const char* aName) {
return InitHighResolutionWithNamedFuncCallback(
aFunc, aClosure, TimeDuration::FromMilliseconds(aDelay), aType, aName);
}
nsresult nsTimerImpl::InitHighResolutionWithNamedFuncCallback(
nsTimerCallbackFunc aFunc, void* aClosure, const TimeDuration& aDelay,
uint32_t aType, const char* aName) {
if (NS_WARN_IF(!aFunc)) {
return NS_ERROR_INVALID_ARG;
}
@ -437,7 +459,8 @@ nsresult nsTimerImpl::Init(nsIObserver* aObserver, uint32_t aDelayInMs,
Callback cb{nsCOMPtr{aObserver}};
MutexAutoLock lock(mMutex);
return InitCommon(aDelayInMs, aType, std::move(cb), lock);
return InitCommon(TimeDuration::FromMilliseconds(aDelayInMs), aType,
std::move(cb), lock);
}
nsresult nsTimerImpl::InitWithClosureCallback(

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

@ -99,9 +99,6 @@ class nsTimerImpl {
mozilla::Variant<UnknownCallback, InterfaceCallback, ObserverCallback,
FuncCallback, ClosureCallback>;
nsresult InitCommon(uint32_t aDelayMS, uint32_t aType, Callback&& newCallback,
const mozilla::MutexAutoLock& aProofOfLock);
nsresult InitCommon(const mozilla::TimeDuration& aDelay, uint32_t aType,
Callback&& newCallback,
const mozilla::MutexAutoLock& aProofOfLock);