Hello Felix,
On 10/18/2010 4:58 PM, Felix Schwarz wrote:
Hi,
today I read again source code for Trac's ComponentManager while
debugging an issue. In the process I found that the code is prone to
race-conditions:
Yup, it's a known issue, it just didn't get high enough on the priority
list so far.
Jun Omae reported issue #9418 some times ago, and I reported #8658 even
earlier.
def maybe_init(self, compmgr, init=init, cls=new_class):
if cls not in compmgr.components:
compmgr.components[cls] = self
if init:
try:
init(self)
except:
del compmgr.components[cls]
raise
…
So is is a small time window where the process-wide dict contains
instances which have not been initialized. That caused some pretty
weird errors for us.
Obviously the correct solution is to add a lock before accessing the
compmgr.components.
However there is also a version which does not need any locks:
def maybe_init(self, compmgr, init=init, cls=new_class):
if cls not in compmgr.components:
if init:
init(self)
compmgr.components[cls] = self
…
So this is exactly the same solution as the one I proposed for #8658; I
suppose this validates it ;-)
I think the above version should work just as well as the current one
while preventing half-initialized instances in the cache, provided
that some basic assumptions are met:
- "compmgr.components[cls] = self" is atomic
- calling a constructor twice in the worst case is not a problem
- two components do not instantiate each others within their __init__
methods (currently the other gets a half-initialized version, the
latter version will cause an endless loop as two normal Python
objects would)
Comments?
I think we can adopt the simple solution for 0.12.2.
Jun came with an even better fix on #9418
(http://trac.edgewall.org/attachment/ticket/9418/9416-r9841-without-lock.diff)
that we should probably apply on trunk. Now that you're familiar with
the problem, you should perhaps also review and comment on that solution.
-- Christian
--
You received this message because you are subscribed to the Google Groups "Trac
Development" group.
To post to this group, send email to trac-...@googlegroups.com.
To unsubscribe from this group, send email to
trac-dev+unsubscr...@googlegroups.com.
For more options, visit this group at
http://groups.google.com/group/trac-dev?hl=en.