diff options
| author | Xavier Morel <xmo@odoo.com> | 2020-09-11 06:14:32 +0000 |
|---|---|---|
| committer | Xavier Morel <xmo@odoo.com> | 2020-09-11 10:59:02 +0000 |
| commit | bb382678ab76bb7cf9543de32ed1a96119ebae18 (patch) | |
| tree | 93159d13dd2f6410a59f311385c083589bf73979 /odoo | |
| parent | c507889384ce262d999639370838226c871a1d48 (diff) | |
[FIX] core: remove callbacks from queue before invocation
The callbacks system is not re-entrant: because we were only clearing
the callbacks after having executed them all, if one of the
post-commit callbacks commits then all the callbacks will get
re-executed (including the one which commits). Which at best can lead
to odd effects & data corruption and at worst crashing the software
because we're overflowing the stack (or maybe the other way around,
hard-crashing might be a better idea than unexpectedly calling the
same functions multiple times).
By popping the callbacks before executing them, we ensure that each
one will only get called once (unless it's explicitely re-pushed on
the stack).
closes odoo/odoo#57509
X-original-commit: 4257be4d771605ecd972bd5b04cb9c0f1163b455
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
Diffstat (limited to 'odoo')
| -rw-r--r-- | odoo/tools/misc.py | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/odoo/tools/misc.py b/odoo/tools/misc.py index 5173e046467..4ecdb6015ef 100644 --- a/odoo/tools/misc.py +++ b/odoo/tools/misc.py @@ -1133,7 +1133,7 @@ class Callbacks: __slots__ = ['_funcs', 'data'] def __init__(self): - self._funcs = [] + self._funcs = collections.deque() self.data = {} def add(self, func): @@ -1141,8 +1141,10 @@ class Callbacks: self._funcs.append(func) def run(self): - """ Call all the functions (in addition order), then clear. """ - for func in self._funcs: + """ Call all the functions (in addition order), then clear associated data. + """ + while self._funcs: + func = self._funcs.popleft() func() self.clear() |
