summaryrefslogtreecommitdiff
path: root/odoo/tools
diff options
context:
space:
mode:
authorXavier Morel <xmo@odoo.com>2020-09-11 06:14:32 +0000
committerXavier Morel <xmo@odoo.com>2020-09-11 10:59:02 +0000
commitbb382678ab76bb7cf9543de32ed1a96119ebae18 (patch)
tree93159d13dd2f6410a59f311385c083589bf73979 /odoo/tools
parentc507889384ce262d999639370838226c871a1d48 (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/tools')
-rw-r--r--odoo/tools/misc.py8
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()