[FIX] component: resolve a subtle concurrency issue

Asynchronous rendering is subtle. Before this commit, it was possible
(though not easy) to get into a situation where the Owl rendering
pipeline decremented twice the counter of a fiber that indicates that
its work is complete.

The situation occurs in the `render` method, where we create a fiber,
wait for a micro tick before starting the actual rendering (the goal was
to batch all changes coming from a single call stack). However, in this
microtask tick, it was possible that the fiber was cancelled, and we did
not have a check for that.
This commit is contained in:
Géry Debongnie
2020-02-06 22:35:41 +01:00
committed by aab-odoo
parent 3fdc7a48f3
commit ee956a1977
2 changed files with 217 additions and 0 deletions
+3
View File
@@ -373,6 +373,9 @@ export class Component<Props extends {} = any, T extends Env = Env> {
const fiber = new Fiber(null, this, force, null);
Promise.resolve().then(() => {
if (__owl__.isMounted || !isMounted) {
if (fiber.isCompleted) {
return;
}
// we are mounted (__owl__.isMounted), or if we are currently being
// mounted (!isMounted), so we call __render
this.__render(fiber);