You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The PrefixList trait type has a hidden thread-safety trap, resulting from the mutable state stored on a PrefixList instance. Given
classA(HasTraits):
foo=PrefixList(["no", "yes"])
two separate instances of A being used on different threads can interact via the values_ cache held on the PrefixList objects. For example, one thread might put a new element into the values_ cache while the other thread is attempting to iterate over it to find a value being looked up, leading to a "dictionary changed size during iteration" error.
A similar situation could occur with a single PrefixList instance shared across multiple classes:
For example, one thread might put a new element into the values_ cache while the other thread is attempting to iterate over it to find a value being looked up, leading to a "dictionary changed size during iteration" error.
This can't happen: we never iterate over the values_ cache. The only things we do with values_ are:
containment checks: (if value in self.values_)
lookups (return self.values_[value], having already established that the value is in self.values_)
assignments: self.values_[value] = match
There's a race condition in the containment check followed by the lookup, but since items are never deleted, the only failure mode there is that we can end up unnecessarily assigning a key to the dict that's already present.
Since self.values_ is a plain dict, and in current Python all of these operations are atomic, we're safe thanks to the GIL.
I still don't like this much, but it doesn't appear to be causing any actual problems right now.
The
PrefixList
trait type has a hidden thread-safety trap, resulting from the mutable state stored on aPrefixList
instance. Giventwo separate instances of
A
being used on different threads can interact via thevalues_
cache held on thePrefixList
objects. For example, one thread might put a new element into thevalues_
cache while the other thread is attempting to iterate over it to find a value being looked up, leading to a "dictionary changed size during iteration" error.A similar situation could occur with a single
PrefixList
instance shared across multiple classes:We may want to consider using an LRU cache from the standard library, which has thread safety built in.
The
PrefixMap
class has a similar issue.The text was updated successfully, but these errors were encountered: