Edgewall Software

Ticket #9418: 9418-r9841.diff

File 9418-r9841.diff, 2.8 KB (added by jomae, 2 years ago)
  • trac/core.py

    diff --git a/trac/core.py b/trac/core.py
    index f2b92b6..4ff8f2b 100644
    a b  
    1616# Author: Jonas Borgström <jonas@edgewall.com> 
    1717#         Christopher Lenz <cmlenz@gmx.de> 
    1818 
     19try: 
     20    import threading 
     21except ImportError: 
     22    import dummy_threading as threading 
     23 
     24 
    1925__all__ = ['Component', 'ExtensionPoint', 'implements', 'Interface', 
    2026           'TracError'] 
    2127 
    class ComponentMeta(type): 
    112118                             and '__init__' in b.__dict__]: 
    113119                    break 
    114120            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) 
    123123            maybe_init._original = init 
    124124            new_class.__init__ = maybe_init 
    125125 
    class ComponentMeta(type): 
    137137 
    138138        return new_class 
    139139 
     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 
    140166 
    141167class Component(object): 
    142168    """Base class for components. 
    class ComponentManager(object): 
    194220        self.enabled = {} 
    195221        if isinstance(self, Component): 
    196222            self.components[self.__class__] = self 
     223        self._lock = threading.RLock() 
     224        self._component_locks = {} 
    197225 
    198226    def __contains__(self, cls): 
    199227        """Return wether the given class is in the list of active components.""" 
    class ComponentManager(object): 
    247275        be available. 
    248276        """ 
    249277        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