web/ldt/utils/threading.py
changeset 22 83b28fc0d731
equal deleted inserted replaced
20:20c41a7e2173 22:83b28fc0d731
       
     1 import threading
       
     2 import inspect
       
     3 import ctypes
       
     4  
       
     5 def _async_raise(tid, exctype):
       
     6     """raises the exception, performs cleanup if needed"""
       
     7     if not inspect.isclass(exctype):
       
     8         raise TypeError("Only types can be raised (not instances)")
       
     9     res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))
       
    10     if res == 0:
       
    11         raise ValueError("invalid thread id")
       
    12     elif res != 1:
       
    13         # """if it returns a number greater than one, you're in trouble, 
       
    14         # and you should call it again with exc=NULL to revert the effect"""
       
    15         ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, 0)
       
    16         raise SystemError("PyThreadState_SetAsyncExc failed")
       
    17  
       
    18  
       
    19 class Thread(threading.Thread):
       
    20     def _get_my_tid(self):
       
    21         """determines this (self's) thread id"""
       
    22         if not self.isAlive():
       
    23             raise threading.ThreadError("the thread is not active")
       
    24  
       
    25         # do we have it cached?
       
    26         if hasattr(self, "_thread_id"):
       
    27             return self._thread_id
       
    28  
       
    29         # no, look for it in the _active dict
       
    30         for tid, tobj in threading._active.items():
       
    31             if tobj is self:
       
    32                 self._thread_id = tid
       
    33                 return tid
       
    34  
       
    35         raise AssertionError("could not determine the thread's id")
       
    36  
       
    37     def raise_exc(self, exctype):
       
    38         """raises the given exception type in the context of this thread"""
       
    39         _async_raise(self._get_my_tid(), exctype)
       
    40  
       
    41     def terminate(self):
       
    42         """raises SystemExit in the context of the given thread, which should 
       
    43         cause the thread to exit silently (unless caught)"""
       
    44         self.raise_exc(SystemExit)