Skip to content

Commit

Permalink
Merge pull request #3405 from jsiirola/config-init-threaded
Browse files Browse the repository at this point in the history
Fix ConfigValue initialization in multithreaded environments
  • Loading branch information
blnicho authored Nov 7, 2024
2 parents 9b1f60e + 12a3e78 commit 8e8280c
Showing 1 changed file with 26 additions and 1 deletion.
27 changes: 26 additions & 1 deletion pyomo/common/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -1708,7 +1708,32 @@ def _data(self):

@_data.setter
def _data(self, value):
self.__class__ = self.__class__.__mro__[2]
_mro = self.__class__.__mro__
# There is an edge case in multithreaded environments where this
# function could actually be called more than once for a single
# ConfigValue. We want to make sure that only the first of the
# calls actually updates the __class__ (the others will
# recursively lookup the _data attribute and the second lookup
# will resolve to normal attribute assignment).
#
# We first encountered this issue for Config objects stores as
# class attributes (i.e., the default Config for something like
# a solver or writer) and multiple threads were simultaneously
# creating instances of the class (each of which was resolving
# the default values for the class attribute).
#
# Note that this explicitly assumes that the uninitialized
# Config object was defined as:
#
# class UninitializedConfig(UninitializedMixin, Config)
#
# and that the resulting class was never inherited from. If
# this assumption is ever violated, attempts to use the
# uninitialized config object will generate infinite recursion
# (and that is OK, as the developer should immediately be
# informed of their error)
if _mro[1] is UninitializedMixin:
self.__class__ = _mro[2]
self._data = value


Expand Down

0 comments on commit 8e8280c

Please sign in to comment.