diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2008-05-02 18:23:16 +0000 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2008-05-02 18:23:16 +0000 |
| commit | 99f02b59af47bdf776fa9f569dd0e97950ca6514 (patch) | |
| tree | 5ea1239b00c0c4426d7ef3073458d8d10fabe188 /lib/sqlalchemy/orm | |
| parent | 0e3021baf431cb9a77335132af7a6dad1f7fa298 (diff) | |
| download | sqlalchemy-99f02b59af47bdf776fa9f569dd0e97950ca6514.tar.gz | |
- fixed reentrant mapper compile hang when
a declared attribute is used within ForeignKey,
ie. ForeignKey(MyOtherClass.someattribute)
Diffstat (limited to 'lib/sqlalchemy/orm')
| -rw-r--r-- | lib/sqlalchemy/orm/mapper.py | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py index 15044ba34..ba0644758 100644 --- a/lib/sqlalchemy/orm/mapper.py +++ b/lib/sqlalchemy/orm/mapper.py @@ -24,7 +24,8 @@ from sqlalchemy.orm.util import has_identity, _state_has_identity, _is_mapped_cl __all__ = ['Mapper', 'class_mapper', 'object_mapper', '_mapper_registry'] _mapper_registry = weakref.WeakKeyDictionary() -__new_mappers = False +_new_mappers = False +_already_compiling = False # a list of MapperExtensions that will be installed in all mappers by default global_extensions = [] @@ -35,7 +36,7 @@ global_extensions = [] NO_ATTRIBUTE = util.symbol('NO_ATTRIBUTE') # lock used to synchronize the "mapper compile" step -_COMPILE_MUTEX = util.threading.Lock() +_COMPILE_MUTEX = util.threading.RLock() # initialize these lazily ColumnProperty = None @@ -179,8 +180,8 @@ class Mapper(object): self.__compile_extensions() self.__compile_properties() self.__compile_pks() - global __new_mappers - __new_mappers = True + global _new_mappers + _new_mappers = True self.__log("constructed") def __log(self, msg): @@ -327,14 +328,20 @@ class Mapper(object): repeatedly. """ - global __new_mappers - if self.__props_init and not __new_mappers: + global _new_mappers + if self.__props_init and not _new_mappers: return self + _COMPILE_MUTEX.acquire() + global _already_compiling + if _already_compiling: + self.__initialize_properties() + return + _already_compiling = True try: # double-check inside mutex - if self.__props_init and not __new_mappers: + if self.__props_init and not _new_mappers: return self # initialize properties on all mappers @@ -342,9 +349,10 @@ class Mapper(object): if not mapper.__props_init: mapper.__initialize_properties() - __new_mappers = False + _new_mappers = False return self finally: + _already_compiling = False _COMPILE_MUTEX.release() def __initialize_properties(self): |
