diff --git a/trac/core.py b/trac/core.py
index f2b92b6..4ff8f2b 100644
|
a
|
b
|
|
| 16 | 16 | # Author: Jonas Borgström <jonas@edgewall.com> |
| 17 | 17 | # Christopher Lenz <cmlenz@gmx.de> |
| 18 | 18 | |
| | 19 | try: |
| | 20 | import threading |
| | 21 | except ImportError: |
| | 22 | import dummy_threading as threading |
| | 23 | |
| | 24 | |
| 19 | 25 | __all__ = ['Component', 'ExtensionPoint', 'implements', 'Interface', |
| 20 | 26 | 'TracError'] |
| 21 | 27 | |
| … |
… |
class ComponentMeta(type): |
| 112 | 118 | and '__init__' in b.__dict__]: |
| 113 | 119 | break |
| 114 | 120 | def maybe_init(self, compmgr, init=init, cls=new_class): |
| 115 | | if cls not in compmgr.components: |
| 116 | | compmgr.components[cls] = self |
| 117 | | if init: |
| 118 | | try: |
| 119 | | init(self) |
| 120 | | except: |
| 121 | | del compmgr.components[cls] |
| 122 | | raise |
| | 121 | if init: |
| | 122 | init(self) |
| 123 | 123 | maybe_init._original = init |
| 124 | 124 | new_class.__init__ = maybe_init |
| 125 | 125 | |
| … |
… |
class ComponentMeta(type): |
| 137 | 137 | |
| 138 | 138 | return new_class |
| 139 | 139 | |
| | 140 | def __call__(cls, *args, **kwargs): |
| | 141 | if issubclass(cls, ComponentManager) or not args: |
| | 142 | return type.__call__(cls, *args, **kwargs) |
| | 143 | |
| | 144 | compmgr = args[0] |
| | 145 | compmgr.acquire_lock() |
| | 146 | try: |
| | 147 | self = compmgr.components.get(cls) |
| | 148 | if self is not None: |
| | 149 | return self |
| | 150 | lock = compmgr.get_component_lock(cls) |
| | 151 | finally: |
| | 152 | compmgr.release_lock() |
| | 153 | |
| | 154 | lock.acquire() |
| | 155 | try: |
| | 156 | self = compmgr.components.get(cls) |
| | 157 | if self is not None: |
| | 158 | return self |
| | 159 | self = cls.__new__(cls, *args, **kwargs) |
| | 160 | self.__init__(*args, **kwargs) |
| | 161 | compmgr.components[cls] = self |
| | 162 | return self |
| | 163 | finally: |
| | 164 | lock.release() |
| | 165 | |
| 140 | 166 | |
| 141 | 167 | class Component(object): |
| 142 | 168 | """Base class for components. |
| … |
… |
class ComponentManager(object): |
| 194 | 220 | self.enabled = {} |
| 195 | 221 | if isinstance(self, Component): |
| 196 | 222 | self.components[self.__class__] = self |
| | 223 | self._lock = threading.RLock() |
| | 224 | self._component_locks = {} |
| 197 | 225 | |
| 198 | 226 | def __contains__(self, cls): |
| 199 | 227 | """Return wether the given class is in the list of active components.""" |
| … |
… |
class ComponentManager(object): |
| 247 | 275 | be available. |
| 248 | 276 | """ |
| 249 | 277 | return True |
| | 278 | |
| | 279 | def acquire_lock(self): |
| | 280 | self._lock.acquire() |
| | 281 | |
| | 282 | def release_lock(self): |
| | 283 | self._lock.release() |
| | 284 | |
| | 285 | def get_component_lock(self, component): |
| | 286 | lock = self._component_locks.get(component) |
| | 287 | if not lock: |
| | 288 | lock = threading.RLock() |
| | 289 | self._component_locks[component] = lock |
| | 290 | return lock |
| | 291 | |