зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
8ee5b6a296
Коммит
95126c57ea
|
@ -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
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче