diff --git a/trac/core.py b/trac/core.py
index f2b92b6..4ff8f2b 100644
--- a/trac/core.py
+++ b/trac/core.py
@@ -16,6 +16,12 @@
 # Author: Jonas Borgström <jonas@edgewall.com>
 #         Christopher Lenz <cmlenz@gmx.de>
 
+try:
+    import threading
+except ImportError:
+    import dummy_threading as threading
+
+
 __all__ = ['Component', 'ExtensionPoint', 'implements', 'Interface',
            'TracError']
 
@@ -112,14 +118,8 @@ class ComponentMeta(type):
                              and '__init__' in b.__dict__]:
                     break
             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
+                if init:
+                    init(self)
             maybe_init._original = init
             new_class.__init__ = maybe_init
 
@@ -137,6 +137,32 @@ class ComponentMeta(type):
 
         return new_class
 
+    def __call__(cls, *args, **kwargs):
+        if issubclass(cls, ComponentManager) or not args:
+            return type.__call__(cls, *args, **kwargs)
+
+        compmgr = args[0]
+        compmgr.acquire_lock()
+        try:
+            self = compmgr.components.get(cls)
+            if self is not None:
+                return self
+            lock = compmgr.get_component_lock(cls)
+        finally:
+            compmgr.release_lock()
+
+        lock.acquire()
+        try:
+            self = compmgr.components.get(cls)
+            if self is not None:
+                return self
+            self = cls.__new__(cls, *args, **kwargs)
+            self.__init__(*args, **kwargs)
+            compmgr.components[cls] = self
+            return self
+        finally:
+            lock.release()
+
 
 class Component(object):
     """Base class for components.
@@ -194,6 +220,8 @@ class ComponentManager(object):
         self.enabled = {}
         if isinstance(self, Component):
             self.components[self.__class__] = self
+        self._lock = threading.RLock()
+        self._component_locks = {}
 
     def __contains__(self, cls):
         """Return wether the given class is in the list of active components."""
@@ -247,3 +275,17 @@ class ComponentManager(object):
         be available.
         """
         return True
+
+    def acquire_lock(self):
+        self._lock.acquire()
+
+    def release_lock(self):
+        self._lock.release()
+
+    def get_component_lock(self, component):
+        lock = self._component_locks.get(component)
+        if not lock:
+            lock = threading.RLock()
+            self._component_locks[component] = lock
+        return lock
+

