jayven avatar jayven committed 0231a1e

Make _hook_excpetion basicly thread-safe

Comments (0)

Files changed (1)

 # -*- coding: utf-8 -*-
 # vim: set ai et si ts=4 sts=4 sw=4:
 
-import sys
+import sys, threading
+
+
+# thread-local storage for hotdebug
+_hotdebug_tls = threading.local()
+
+
+def register_exception_callback(cb):
+    _hotdebug_tls.exception_callback = cb
+
+
+def unregister_exception_callback():
+    if getattr(_hotdebug_tls, 'exception_callback', None):
+        del _hotdebug_tls.exception_callback
 
 
 def _hook_excpetion():
 
-    # id->callback to call when exception is caught
-    _exception_cb = {}
-    
-    def register_exception_cb(id, cb):
-        _exception_cb[id] = cb
-
-    def unregister_exception_cb(id):
-        _exception_cb.pop(id, None)
-
     def _wrap_dispatch(old):
         def dispatch(self, method, auth, params):
             try:
                 return old(self, method, auth, params)
             except:
-                t, v, tb = sys.exc_info() 
-                for cb in _exception_cb.itervalues():
-                    cb(t, v, tb)
+                cb = getattr(_hotdebug_tls, 'exception_callback', None)
+                # only process the same thread's exception
+                if cb is not None:
+                    cb(*sys.exc_info())
                 raise
+        dispatch._hooked = True
         return dispatch
 
     from netsvc import ExportService
     for service in ExportService._services.itervalues():
         dispatch = service.__class__.__dict__.get('dispatch', None)
-        if dispatch:
+        if dispatch and getattr(dispatch, '_hooked', False):
             service.__class__.dispatch = _wrap_dispatch(dispatch)
 
-    return register_exception_cb, unregister_exception_cb
 
-
-register_exception_cb, unregister_exception_cb = _hook_excpetion()
+_hook_excpetion()
 del _hook_excpetion
 
 
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.