CURA-4848 Global stack now does its infinite resolve prevention on per thread basis

This commit is contained in:
Jack Ha 2018-01-23 16:17:38 +01:00
parent cde3799702
commit def86defe6

View file

@ -1,6 +1,8 @@
# Copyright (c) 2017 Ultimaker B.V. # Copyright (c) 2017 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from collections import defaultdict
import threading
from typing import Any, Dict, Optional from typing import Any, Dict, Optional
from PyQt5.QtCore import pyqtProperty from PyQt5.QtCore import pyqtProperty
@ -30,7 +32,8 @@ class GlobalStack(CuraContainerStack):
# This property is used to track which settings we are calculating the "resolve" for # This property is used to track which settings we are calculating the "resolve" for
# and if so, to bypass the resolve to prevent an infinite recursion that would occur # and if so, to bypass the resolve to prevent an infinite recursion that would occur
# if the resolve function tried to access the same property it is a resolve for. # if the resolve function tried to access the same property it is a resolve for.
self._resolving_settings = set() # Per thread we have our own resolving_settings, or strange things sometimes occur.
self._resolving_settings = defaultdict(set) # keys are thread names
## Get the list of extruders of this stack. ## Get the list of extruders of this stack.
# #
@ -91,16 +94,10 @@ class GlobalStack(CuraContainerStack):
# Handle the "resolve" property. # Handle the "resolve" property.
if self._shouldResolve(key, property_name, context): if self._shouldResolve(key, property_name, context):
self._resolving_settings.add(key) current_thread = threading.current_thread()
self._resolving_settings[current_thread.name].add(key)
resolve = super().getProperty(key, "resolve", context) resolve = super().getProperty(key, "resolve", context)
if key not in self._resolving_settings: self._resolving_settings[current_thread.name].remove(key)
# For debugging CURA-4848, if it happens
Logger.log("e", "Key [%s] should really have been in set(%s). Now I'm gonna crash", key, str(self._resolving_settings))
Logger.log("d", "------ context ------")
for stack in context.stack_of_containers:
Logger.log("d", "Context: %s", stack.getId())
Logger.log("d", "------ context end ------")
self._resolving_settings.remove(key)
if resolve is not None: if resolve is not None:
return resolve return resolve
@ -152,7 +149,8 @@ class GlobalStack(CuraContainerStack):
# Do not try to resolve anything but the "value" property # Do not try to resolve anything but the "value" property
return False return False
if key in self._resolving_settings: current_thread = threading.current_thread()
if key in self._resolving_settings[current_thread.name]:
# To prevent infinite recursion, if getProperty is called with the same key as # To prevent infinite recursion, if getProperty is called with the same key as
# we are already trying to resolve, we should not try to resolve again. Since # we are already trying to resolve, we should not try to resolve again. Since
# this can happen multiple times when trying to resolve a value, we need to # this can happen multiple times when trying to resolve a value, we need to