Bug 1404997 - P18. Add Await convenience methods. r=gerald

Takes either a MozPromise or an AllPromiseType and will execute the resolve/reject functions synchronously once the promise has resolved/rejected.

MozReview-Commit-ID: EyfMTPtA1Lu

--HG--
extra : rebase_source : 780ab41307158d7887cd76782e43693079f78c91
This commit is contained in:
Jean-Yves Avenard 2017-12-08 13:35:29 +01:00
Родитель 8ee5b6a296
Коммит 95126c57ea
1 изменённых файлов: 121 добавлений и 0 удалений

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

@ -7,7 +7,12 @@
#ifndef mozilla_MediaUtils_h
#define mozilla_MediaUtils_h
#include "AutoTaskQueue.h"
#include "mozilla/Assertions.h"
#include "mozilla/Monitor.h"
#include "mozilla/MozPromise.h"
#include "mozilla/RefPtr.h"
#include "mozilla/SharedThreadPool.h"
#include "mozilla/UniquePtr.h"
#include "nsCOMPtr.h"
#include "nsIAsyncShutdown.h"
@ -410,6 +415,122 @@ private:
nsCOMPtr<nsIAsyncShutdownBlocker> mBlocker;
};
/**
* Await convenience methods to block until the promise has been resolved or
* rejected. The Resolve/Reject functions, while called on a different thread,
* would be running just as on the current thread thanks to the memory barrier
* provided by the monitor.
* For now Await can only be used with an exclusive MozPromise if passed a
* Resolve/Reject function.
*/
template<typename ResolveValueType,
typename RejectValueType,
typename ResolveFunction,
typename RejectFunction>
void
Await(
RefPtr<MozPromise<ResolveValueType, RejectValueType, true>> aPromise,
ResolveFunction&& aResolveFunction,
RejectFunction&& aRejectFunction)
{
Monitor mon(__func__);
RefPtr<AutoTaskQueue> taskQueue = new AutoTaskQueue(
SharedThreadPool::Get(NS_LITERAL_CSTRING("AwaitMozPromise")));
bool done = false;
aPromise->Then(taskQueue,
__func__,
[&](ResolveValueType&& aResolveValue) {
MonitorAutoLock lock(mon);
aResolveFunction(Forward<ResolveValueType>(aResolveValue));
done = true;
mon.Notify();
},
[&](RejectValueType&& aRejectValue) {
MonitorAutoLock lock(mon);
aRejectFunction(Forward<RejectValueType>(aRejectValue));
done = true;
mon.Notify();
});
MonitorAutoLock lock(mon);
while (!done) {
mon.Wait();
}
}
template<typename ResolveValueType, typename RejectValueType, bool Excl>
typename MozPromise<ResolveValueType, RejectValueType, Excl>::
ResolveOrRejectValue
Await(RefPtr<MozPromise<ResolveValueType, RejectValueType, Excl>> aPromise)
{
Monitor mon(__func__);
RefPtr<AutoTaskQueue> taskQueue = new AutoTaskQueue(
SharedThreadPool::Get(NS_LITERAL_CSTRING("AwaitMozPromise")));
bool done = false;
typename MozPromise<ResolveValueType, RejectValueType, Excl>::ResolveOrRejectValue val;
aPromise->Then(taskQueue,
__func__,
[&](ResolveValueType aResolveValue) {
val.SetResolve(Move(aResolveValue));
MonitorAutoLock lock(mon);
done = true;
mon.Notify();
},
[&](RejectValueType aRejectValue) {
val.SetReject(Move(aRejectValue));
MonitorAutoLock lock(mon);
done = true;
mon.Notify();
});
MonitorAutoLock lock(mon);
while (!done) {
mon.Wait();
}
return val;
}
/**
* Similar to Await, takes an array of promises of the same type.
* MozPromise::All is used to handle the resolution/rejection of the promises.
*/
template<typename ResolveValueType,
typename RejectValueType,
typename ResolveFunction,
typename RejectFunction>
void
AwaitAll(nsTArray<RefPtr<MozPromise<ResolveValueType, RejectValueType, true>>>&
aPromises,
ResolveFunction&& aResolveFunction,
RejectFunction&& aRejectFunction)
{
typedef MozPromise<ResolveValueType, RejectValueType, true> Promise;
RefPtr<AutoTaskQueue> taskQueue = new AutoTaskQueue(
SharedThreadPool::Get(NS_LITERAL_CSTRING("AwaitMozPromise")));
RefPtr<typename Promise::AllPromiseType> p = Promise::All(taskQueue, aPromises);
Await(p, Move(aResolveFunction), Move(aRejectFunction));
}
// Note: only works with exclusive MozPromise, as Promise::All would attempt
// to perform copy of nsTArrays which are disallowed.
template<typename ResolveValueType, typename RejectValueType>
typename MozPromise<ResolveValueType,
RejectValueType,
true>::AllPromiseType::ResolveOrRejectValue
AwaitAll(nsTArray<RefPtr<MozPromise<ResolveValueType, RejectValueType, true>>>&
aPromises)
{
typedef MozPromise<ResolveValueType, RejectValueType, true> Promise;
RefPtr<AutoTaskQueue> taskQueue = new AutoTaskQueue(
SharedThreadPool::Get(NS_LITERAL_CSTRING("AwaitMozPromise")));
RefPtr<typename Promise::AllPromiseType> p =
Promise::All(taskQueue, aPromises);
return Await(p);
}
} // namespace media
} // namespace mozilla