_mapper_registry is not appropriately mutex-protected

Issue #1874 resolved
Former user created an issue

I found this bug in 0.5.5, but the source for 0.6.3 seems to contain the same bug. In lib/sqlalchemy/orm/mapper.py, _mapper_registry is mutex-protected only in Mapper.compile(), not when new Mapper instances are created (or deleted). This leads to odd race conditions when SQLAlchemy is being used in threaded contexts (e.g., under CherryPy).

Comments (2)

  1. Mike Bayer repo owner

    I think you aren't looking at 0.6.3, here's the source, from http://www.sqlalchemy.org/trac/browser/lib/sqlalchemy/orm/mapper.py#L200:

            # prevent this mapper from being constructed
            # while a compile() is occuring (and defer a compile()
            # until construction succeeds)
            _COMPILE_MUTEX.acquire()
            try:
                self._configure_inheritance()
                self._configure_extensions()
                self._configure_class_instrumentation()
                self._configure_properties()
                self._configure_pks()
                global _new_mappers
                _new_mappers = True
                self._log("constructed")
            finally:
                _COMPILE_MUTEX.release()
    

    _mapper_registry is mutated in _configure_class_instrumentation. This code was the direct result of a previous bug report and has long since been resolved in 0.6.

    On the dispose side the WeakKeyDictionary handles removals, we use list() against the registry when running through an iteration of it in order to be somewhat defensive about this, though removal of mappers in a running web application is not a primary use case.

  2. Log in to comment