wasm: Fix handling of promise pool in WebPromiseManager
Promises are registered upon entry to the pool and unregistered upon exit. If all promises are in a 'pending' state, new promises can't be processed. Upon completion of a registered promise, it is unregistered, allowing space for a new promise. The code path responsible for unregistering promises when they resolve runs each time a promise's callback is called. Unfortunately, there's no guarantee that the callback will be invoked upon the promise's resolution. For instance, promises registered with only a 'catch' callback may never be triggered when the promise resolves correctly. This commit ensures that a final callback is always registered, even if the user did not provide one. This guarantees that promises are always unregistered upon resolution Fixes: QTBUG-118161 Pick-to: 6.5 Change-Id: Ifea93d692464a6ef40c4bcad60f840ca0cb650c9 Reviewed-by: Lorn Potter <lorn.potter@gmail.com> (cherry picked from commit 1e6841245dca3bda5dee050fc841c7129142dd9f) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> (cherry picked from commit a625d521f70c4897ba4ebeb7f1c7195e571290fb)
This commit is contained in:
parent
ee0b32d77f
commit
129ab89c5d
@ -136,11 +136,12 @@ public:
|
||||
"catch",
|
||||
emscripten::val::module_property(thunkName(CallbackType::Catch, id()).data()));
|
||||
}
|
||||
if (callbacks.finallyFunc) {
|
||||
// Guarantee the invocation of at least one callback by always
|
||||
// registering 'finally'. This is required by WebPromiseManager
|
||||
// design
|
||||
target = target.call<val>(
|
||||
"finally",
|
||||
emscripten::val::module_property(thunkName(CallbackType::Finally, id()).data()));
|
||||
}
|
||||
"finally", emscripten::val::module_property(
|
||||
thunkName(CallbackType::Finally, id()).data()));
|
||||
}
|
||||
|
||||
private:
|
||||
@ -321,25 +322,21 @@ void WebPromiseManager::promiseThunkCallback(int context, CallbackType type, ems
|
||||
auto* promiseState = &m_promiseRegistry[context];
|
||||
|
||||
auto* callbacks = &promiseState->callbacks;
|
||||
bool expectingOtherCallbacks;
|
||||
switch (type) {
|
||||
case CallbackType::Then:
|
||||
callbacks->thenFunc(result);
|
||||
// At this point, if there is no finally function, we are sure that the Catch callback won't be issued.
|
||||
expectingOtherCallbacks = !!callbacks->finallyFunc;
|
||||
break;
|
||||
case CallbackType::Catch:
|
||||
callbacks->catchFunc(result);
|
||||
expectingOtherCallbacks = !!callbacks->finallyFunc;
|
||||
break;
|
||||
case CallbackType::Finally:
|
||||
// Final callback may be empty, used solely for promise unregistration
|
||||
if (callbacks->finallyFunc) {
|
||||
callbacks->finallyFunc();
|
||||
expectingOtherCallbacks = false;
|
||||
}
|
||||
unregisterPromise(context);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!expectingOtherCallbacks)
|
||||
unregisterPromise(context);
|
||||
}
|
||||
|
||||
void WebPromiseManager::registerPromise(
|
||||
|
Loading…
x
Reference in New Issue
Block a user