← Back to team overview

openerp-community-reviewer team mailing list archive

[Bug 1238560] Re: RegistryManager: threading.RLock is missing

 

Hello Guewen,

We confirm this could happened and it should be fixed with the lock (we could not reproduce but the analysis seems to confirm it).
We used to have a lock on the get method but it was removed due to deadlock possibilities. This is no longer possible with the current code so we can put the lock back. See my commit message for more information.

revno: 5129 [merge]
revision-id: mat@xxxxxxxxxxx-20131114144401-k00podawlem7cjd1

Thanks for the patch

** Changed in: openobject-server
       Status: Confirmed => Fix Released

-- 
You received this bug notification because you are a member of OpenERP
Community Backports Team, which is subscribed to OpenERP Community
Backports (Server).
https://bugs.launchpad.net/bugs/1238560

Title:
  RegistryManager: threading.RLock is missing

Status in OpenERP Community Backports (Server):
  New
Status in OpenERP Server:
  Fix Released

Bug description:
  Hi,

  I just get caught by this bug, which is very hard to reproduce.

  It happens only when:
   - you have more than 1 thread which starts when a module is loaded
   - a child thread calls openerp.pooler.get_pool()
   - OpenERP is started from an external script, like "behave" or "oe" when running the python tests (does not seems to happen when started from openerp-server)

  It gives errors as this example:

    File ".../server/openerp/service/web_services.py", line 433, in dispatch
      return fn(*params)
    File ".../server/openerp/service/web_services.py", line 438, in exp_login
      res = security.login(db, login, password)
    File ".../server/openerp/service/security.py", line 31, in login
      return user_obj.login(db, login, password)
  AttributeError: 'NoneType' object has no attribute 'login'

  Cause:

  RegistryManager.get() on:
  http://bazaar.launchpad.net/~openerp/openobject-server/7.0/view/5096/openerp/modules/registry.py#L185

  It must be protected by cls.registries_lock because it may return the registry from cls.registries or create a new one.
  What happens when there is no registry and 2 threads calls RegistryManager.get() at the same time:
   1. they both have a KeyError
   2. they both execute RegistryManager.new(). This one is protected by the RLock but that's already too late
   3. the first thread create a new Registry. RegistryManager.get() returns this Registry
   4. then the second thread create a new Registry and replace the first one in cls.registries. RegistryManager.get() returns this Registry
   5. One of the registry (could not see which) has no models => self.pool.get() always returns None

  If RegistryManager.get() had been surrounded by a RLock, the second
  thread would just have waited and would not have created a new
  Registry.

  The branch is coming.

To manage notifications about this bug go to:
https://bugs.launchpad.net/ocb-server/+bug/1238560/+subscriptions